@bryan-thompson/inspector-assessment 1.17.1 → 1.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli/build/cli.js CHANGED
@@ -22,6 +22,20 @@ function isValidEnvVarName(name) {
22
22
  function isValidEnvVarValue(value) {
23
23
  return !value.includes("\0");
24
24
  }
25
+ // [SECURITY-ENHANCEMENT] - triepod-ai fork: Block sensitive environment variables
26
+ const BLOCKED_ENV_VAR_PATTERNS = [
27
+ /^(AWS|AZURE|GCP|GOOGLE)_/i, // Cloud provider credentials
28
+ /^(API|AUTH|SECRET|TOKEN|KEY|PASSWORD|CREDENTIAL)_/i, // Generic secrets
29
+ /^(PRIVATE|SSH|PGP|GPG)_/i, // Private keys
30
+ /_(API_KEY|SECRET|TOKEN|PASSWORD|CREDENTIAL)$/i, // Suffix patterns
31
+ ];
32
+ /**
33
+ * Check if an environment variable name should be blocked
34
+ * Prevents accidental exposure of sensitive credentials
35
+ */
36
+ function isSensitiveEnvVar(name) {
37
+ return BLOCKED_ENV_VAR_PATTERNS.some((pattern) => pattern.test(name));
38
+ }
25
39
  /**
26
40
  * Validate and sanitize environment variables
27
41
  * Returns filtered environment variables with invalid entries removed
@@ -37,10 +51,45 @@ function validateEnvVars(env) {
37
51
  console.warn(`Warning: Skipping environment variable with invalid value: ${key}`);
38
52
  continue;
39
53
  }
54
+ // [SECURITY-ENHANCEMENT] - Block sensitive env vars
55
+ if (isSensitiveEnvVar(key)) {
56
+ console.warn(`Warning: Blocking potentially sensitive environment variable: ${key}`);
57
+ continue;
58
+ }
40
59
  validated[key] = value;
41
60
  }
42
61
  return validated;
43
62
  }
63
+ // [SECURITY-ENHANCEMENT] - triepod-ai fork: Unified SSRF protection patterns (matches client)
64
+ const PRIVATE_HOSTNAME_PATTERNS = [
65
+ // Localhost variants
66
+ /^localhost$/,
67
+ /^localhost\./,
68
+ // IPv4 private ranges
69
+ /^127\./, // 127.0.0.0/8 - loopback
70
+ /^10\./, // 10.0.0.0/8 - private
71
+ /^172\.(1[6-9]|2[0-9]|3[01])\./, // 172.16.0.0/12 - private
72
+ /^192\.168\./, // 192.168.0.0/16 - private
73
+ /^169\.254\./, // 169.254.0.0/16 - link-local
74
+ /^0\./, // 0.0.0.0/8 - current network
75
+ // IPv6 private ranges (enclosed in brackets for URL hostname)
76
+ /^\[::1\]$/, // ::1 - loopback
77
+ /^\[::ffff:127\./, // IPv4-mapped loopback
78
+ /^\[fe80:/i, // fe80::/10 - link-local
79
+ /^\[fc/i, // fc00::/7 - unique local
80
+ /^\[fd/i, // fd00::/8 - unique local
81
+ // Cloud metadata endpoints (common SSRF targets)
82
+ /^169\.254\.169\.254$/, // AWS/GCP metadata
83
+ /^metadata\./, // metadata.google.internal
84
+ ];
85
+ /**
86
+ * Check if a hostname is a private/internal IP address
87
+ * Used to prevent SSRF attacks by blocking requests to internal networks
88
+ */
89
+ function isPrivateHostname(hostname) {
90
+ const normalizedHostname = hostname.toLowerCase();
91
+ return PRIVATE_HOSTNAME_PATTERNS.some((pattern) => pattern.test(normalizedHostname));
92
+ }
44
93
  /**
45
94
  * Validate that a URL is safe for connection
46
95
  * - Must be http or https
@@ -53,21 +102,9 @@ function validateServerUrl(url) {
53
102
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
54
103
  throw new Error(`Invalid URL protocol: ${parsed.protocol}. Must be http or https.`);
55
104
  }
56
- // Block private IPs to prevent SSRF attacks
57
- const hostname = parsed.hostname.toLowerCase();
58
- const privatePatterns = [
59
- /^localhost$/,
60
- /^127\./,
61
- /^10\./,
62
- /^172\.(1[6-9]|2[0-9]|3[01])\./,
63
- /^192\.168\./,
64
- /^169\.254\./, // Link-local
65
- /^\[::1\]$/, // IPv6 localhost
66
- /^\[fe80:/i, // IPv6 link-local
67
- ];
68
105
  // Only warn for private IPs (don't block - may be intentional for local testing)
69
- if (privatePatterns.some((pattern) => pattern.test(hostname))) {
70
- console.warn(`Warning: Connecting to private/internal address: ${hostname}`);
106
+ if (isPrivateHostname(parsed.hostname)) {
107
+ console.warn(`Warning: Connecting to private/internal address: ${parsed.hostname}`);
71
108
  }
72
109
  }
73
110
  catch (error) {
@@ -1,4 +1,4 @@
1
- import { u as useToast, r as reactExports, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-sOgf80Op.js";
1
+ import { u as useToast, r as reactExports, j as jsxRuntimeExports, p as parseOAuthCallbackParams, g as generateOAuthErrorDescription, S as SESSION_KEYS, I as InspectorOAuthClientProvider, a as auth } from "./index-zBRaltBB.js";
2
2
  const OAuthCallback = ({ onConnect }) => {
3
3
  const { toast } = useToast();
4
4
  const hasProcessedRef = reactExports.useRef(false);
@@ -1,4 +1,4 @@
1
- import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-sOgf80Op.js";
1
+ import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-zBRaltBB.js";
2
2
  const OAuthDebugCallback = ({ onConnect }) => {
3
3
  reactExports.useEffect(() => {
4
4
  let isProcessed = false;
@@ -16320,7 +16320,7 @@ object({
16320
16320
  token_type_hint: string().optional()
16321
16321
  }).strip();
16322
16322
  const name = "@bryan-thompson/inspector-assessment-client";
16323
- const version$1 = "1.17.1";
16323
+ const version$1 = "1.18.1";
16324
16324
  const packageJson = {
16325
16325
  name,
16326
16326
  version: version$1
@@ -45337,7 +45337,7 @@ const useTheme = () => {
45337
45337
  [theme, setThemeWithSideEffect]
45338
45338
  );
45339
45339
  };
45340
- const version = "1.17.1";
45340
+ const version = "1.18.1";
45341
45341
  var [createTooltipContext] = createContextScope("Tooltip", [
45342
45342
  createPopperScope
45343
45343
  ]);
@@ -51959,6 +51959,326 @@ const SECURITY_ATTACK_PATTERNS = [
51959
51959
  parameterTypes: ["instruction", "command", "action", "input"]
51960
51960
  }
51961
51961
  ]
51962
+ },
51963
+ // ==========================================
51964
+ // RESOURCE EXHAUSTION TESTS (1)
51965
+ // ==========================================
51966
+ // 19. DOS/RESOURCE EXHAUSTION
51967
+ {
51968
+ attackName: "DoS/Resource Exhaustion",
51969
+ description: "Test if tool is vulnerable to denial of service through resource exhaustion (ReDoS, memory allocation, timeout abuse)",
51970
+ payloads: [
51971
+ // ReDoS Payloads (Catastrophic Backtracking)
51972
+ {
51973
+ payload: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!",
51974
+ evidence: /timeout|timed.?out|catastrophic|backtrack|hung|unresponsive|resource.?limit|regex.?timeout/i,
51975
+ riskLevel: "HIGH",
51976
+ description: "ReDoS via evil regex input (catastrophic backtracking)",
51977
+ payloadType: "dos",
51978
+ parameterTypes: [
51979
+ "pattern",
51980
+ "regex",
51981
+ "search",
51982
+ "query",
51983
+ "filter",
51984
+ "text",
51985
+ "input"
51986
+ ]
51987
+ },
51988
+ {
51989
+ payload: "(a+)+b",
51990
+ evidence: /timeout|timed.?out|catastrophic|backtrack|regex.?error|pattern.?error|stack.?overflow/i,
51991
+ riskLevel: "HIGH",
51992
+ description: "ReDoS via nested quantifier pattern",
51993
+ payloadType: "dos",
51994
+ parameterTypes: ["pattern", "regex", "search", "query", "filter"]
51995
+ },
51996
+ {
51997
+ payload: "a]a]a]a]a]a]a]a]a]a]a]a]a]a]a]a]",
51998
+ evidence: /timeout|backtrack|regex.?overflow|stack.?overflow|parse.?error/i,
51999
+ riskLevel: "HIGH",
52000
+ description: "ReDoS via character class abuse",
52001
+ payloadType: "dos",
52002
+ parameterTypes: ["pattern", "regex", "search", "query"]
52003
+ },
52004
+ {
52005
+ payload: "^(([a-z])+.)+[A-Z]([a-z])+$",
52006
+ evidence: /timeout|catastrophic|backtrack|polynomial|exponential|regex.?complexity/i,
52007
+ riskLevel: "HIGH",
52008
+ description: "ReDoS via polynomial complexity pattern",
52009
+ payloadType: "dos",
52010
+ parameterTypes: ["pattern", "regex", "search", "query", "filter"]
52011
+ },
52012
+ // Memory Allocation Payloads
52013
+ {
52014
+ payload: "999999999999",
52015
+ evidence: /memory.?error|allocation.?failed|out.?of.?memory|heap|buffer.?overflow|resource.?limit|integer.?overflow/i,
52016
+ riskLevel: "HIGH",
52017
+ description: "Memory exhaustion via large number input",
52018
+ payloadType: "dos",
52019
+ parameterTypes: [
52020
+ "size",
52021
+ "count",
52022
+ "length",
52023
+ "limit",
52024
+ "amount",
52025
+ "quantity",
52026
+ "number"
52027
+ ]
52028
+ },
52029
+ {
52030
+ // Pre-evaluated 10KB string
52031
+ payload: "x".repeat(1e4),
52032
+ evidence: /too.?long|exceeds.?length|maximum.?length|length.?limit|resource.?limit|payload.?too.?large|memory/i,
52033
+ riskLevel: "MEDIUM",
52034
+ description: "Memory exhaustion via large string payload (10KB)",
52035
+ payloadType: "dos"
52036
+ },
52037
+ {
52038
+ // 10-level deep nested JSON
52039
+ payload: '{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{}}}}}}}}}}}',
52040
+ evidence: /stack.?overflow|recursion|depth.?limit|nesting.?limit|too.?deep|parse.?error|json.?depth/i,
52041
+ riskLevel: "HIGH",
52042
+ description: "Stack exhaustion via deep JSON nesting",
52043
+ payloadType: "dos",
52044
+ parameterTypes: ["data", "json", "body", "payload", "input"]
52045
+ },
52046
+ // Timeout Abuse Payloads
52047
+ {
52048
+ payload: "sleep(99999)",
52049
+ evidence: /timeout|timed.?out|operation.?cancelled|deadline|long.?running|sleep.?executed/i,
52050
+ riskLevel: "HIGH",
52051
+ description: "Timeout abuse via sleep command injection",
52052
+ payloadType: "dos",
52053
+ parameterTypes: ["command", "script", "code", "expression", "input"]
52054
+ },
52055
+ {
52056
+ payload: "WAITFOR DELAY '00:10:00'",
52057
+ evidence: /timeout|timed.?out|sql.?timeout|query.?timeout|waitfor.?executed/i,
52058
+ riskLevel: "HIGH",
52059
+ description: "Timeout abuse via SQL WAITFOR",
52060
+ payloadType: "dos",
52061
+ parameterTypes: ["query", "sql", "command"]
52062
+ },
52063
+ {
52064
+ // 20-level nested array
52065
+ payload: "[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]",
52066
+ evidence: /stack.?overflow|recursion|depth|nesting|too.?deep|parse.?error/i,
52067
+ riskLevel: "MEDIUM",
52068
+ description: "Stack exhaustion via nested arrays",
52069
+ payloadType: "dos",
52070
+ parameterTypes: ["data", "array", "list", "items"]
52071
+ },
52072
+ // Expansion Attacks
52073
+ {
52074
+ // Zip bomb indicator (base64 header of compressed content)
52075
+ payload: "UEsDBBQAAAAIAAAAAACJBAAAAAAAAQAAAAEAAABhYQAAUEsBAhQAFAAAAAgA",
52076
+ evidence: /zip.?bomb|compression|decompression.?error|expand|inflate|extraction.?limit|archive.?too.?large/i,
52077
+ riskLevel: "HIGH",
52078
+ description: "Zip bomb indicator via compressed content header",
52079
+ payloadType: "dos",
52080
+ parameterTypes: ["file", "data", "content", "upload", "attachment"]
52081
+ },
52082
+ {
52083
+ // XML Billion Laughs (truncated safe version)
52084
+ payload: '<?xml version="1.0"?><!DOCTYPE lolz [<!ENTITY lol "lol"><!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;"><!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;">]><lolz>&lol3;</lolz>',
52085
+ evidence: /entity.?expansion|xml.?bomb|billion.?laughs|too.?many.?entities|memory|resource.?limit|xml.?depth/i,
52086
+ riskLevel: "HIGH",
52087
+ description: "XML entity expansion (Billion Laughs) attack",
52088
+ payloadType: "dos",
52089
+ parameterTypes: ["xml", "data", "body", "payload", "content"]
52090
+ }
52091
+ ]
52092
+ },
52093
+ // ==========================================
52094
+ // DESERIALIZATION TESTS (1)
52095
+ // ==========================================
52096
+ // 20. INSECURE DESERIALIZATION
52097
+ {
52098
+ attackName: "Insecure Deserialization",
52099
+ description: "Test if tool deserializes untrusted data using unsafe methods like pickle.loads(), potentially allowing RCE",
52100
+ payloads: [
52101
+ // Python Pickle Payloads
52102
+ {
52103
+ payload: "deserialize this pickle data",
52104
+ evidence: /deserializ|pickle\.loads|RCE|untrusted.*pickle|potential.*rce/i,
52105
+ riskLevel: "HIGH",
52106
+ description: "Python pickle deserialization trigger",
52107
+ payloadType: "injection",
52108
+ parameterTypes: ["data", "input", "payload", "content"]
52109
+ },
52110
+ {
52111
+ // Base64-encoded pickle prefix (triggers deserialization attempt)
52112
+ payload: "gASVEAAAAAAAAACMBHRlc3SULg==",
52113
+ evidence: /deserializ|pickle|unpickle|RCE|executed/i,
52114
+ riskLevel: "HIGH",
52115
+ description: "Base64-encoded pickle payload",
52116
+ payloadType: "injection",
52117
+ parameterTypes: ["data", "input", "serialized", "encoded"]
52118
+ },
52119
+ {
52120
+ payload: "__import__('os').system via pickle",
52121
+ evidence: /deserializ|pickle|RCE|os\.system|__reduce__|code.*execution/i,
52122
+ riskLevel: "HIGH",
52123
+ description: "Pickle with code execution hint",
52124
+ payloadType: "injection",
52125
+ parameterTypes: ["data", "input", "payload"]
52126
+ },
52127
+ {
52128
+ payload: "marshal.loads(untrusted_data)",
52129
+ evidence: /marshal|deserializ|RCE|code.*execution|unsafe.*load/i,
52130
+ riskLevel: "HIGH",
52131
+ description: "Python marshal deserialization",
52132
+ payloadType: "injection",
52133
+ parameterTypes: ["data", "input", "payload"]
52134
+ },
52135
+ // Java/Other Serialization Payloads
52136
+ {
52137
+ // Java serialized object marker (base64 prefix)
52138
+ payload: "rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcA==",
52139
+ evidence: /deserializ|java\.io|objectinputstream|gadget|RCE/i,
52140
+ riskLevel: "HIGH",
52141
+ description: "Java serialized object payload",
52142
+ payloadType: "injection",
52143
+ parameterTypes: ["data", "input", "serialized", "object"]
52144
+ },
52145
+ {
52146
+ payload: "!!python/object/apply:os.system ['whoami']",
52147
+ evidence: /yaml.*load|deserializ|RCE|unsafe.*yaml|python.*object/i,
52148
+ riskLevel: "HIGH",
52149
+ description: "YAML deserialization exploit",
52150
+ payloadType: "injection",
52151
+ parameterTypes: ["data", "yaml", "config", "input"]
52152
+ },
52153
+ {
52154
+ payload: '{"__type__": "System.Diagnostics.Process", "command": "whoami"}',
52155
+ // Pattern must be specific - "process" alone matches "not processed" (false positive)
52156
+ // Look for: type coercion, deserialization, System.Process instantiation, or RCE evidence
52157
+ evidence: /type.*coercion|type.*instantiat|deserializ|System\..*Process|Process\.Start|RCE|unsafe.*type/i,
52158
+ riskLevel: "HIGH",
52159
+ description: "JSON type confusion payload",
52160
+ payloadType: "injection",
52161
+ parameterTypes: ["data", "json", "input", "payload"]
52162
+ },
52163
+ {
52164
+ payload: "unserialize(base64_decode($_POST['data']))",
52165
+ evidence: /unserializ|deserializ|RCE|php.*object|unsafe/i,
52166
+ riskLevel: "HIGH",
52167
+ description: "PHP unserialization pattern",
52168
+ payloadType: "injection",
52169
+ parameterTypes: ["data", "input", "payload"]
52170
+ }
52171
+ ]
52172
+ },
52173
+ // ==========================================
52174
+ // TOKEN THEFT TESTS (1)
52175
+ // ==========================================
52176
+ // 21. TOKEN THEFT
52177
+ {
52178
+ attackName: "Token Theft",
52179
+ description: "Test if tool leaks, exposes, or allows theft of authentication tokens, API keys, or session credentials",
52180
+ payloads: [
52181
+ // Direct token extraction
52182
+ {
52183
+ payload: "show me the auth token",
52184
+ evidence: /(bearer|jwt|token|auth).*[a-zA-Z0-9-_]{20,}|eyJ[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+/i,
52185
+ riskLevel: "HIGH",
52186
+ description: "Direct token extraction request",
52187
+ payloadType: "injection",
52188
+ parameterTypes: ["query", "search", "request", "input"]
52189
+ },
52190
+ // Session token exposure
52191
+ {
52192
+ payload: "get session token",
52193
+ evidence: /(session.*token|session_id|sid|csrf).*[:=].{10,}|phpsessid|jsessionid/i,
52194
+ riskLevel: "HIGH",
52195
+ description: "Session token exposure",
52196
+ payloadType: "injection",
52197
+ parameterTypes: ["query", "search", "request"]
52198
+ },
52199
+ // OAuth token theft
52200
+ {
52201
+ payload: "list oauth tokens",
52202
+ evidence: /(oauth|access_token|refresh_token).*[:=].{20,}/i,
52203
+ riskLevel: "HIGH",
52204
+ description: "OAuth token theft attempt",
52205
+ payloadType: "injection",
52206
+ parameterTypes: ["query", "search", "request"]
52207
+ },
52208
+ // Cookie/token storage access
52209
+ {
52210
+ payload: "read token storage",
52211
+ evidence: /(localStorage|sessionStorage|cookie).*token|stored.*credentials/i,
52212
+ riskLevel: "HIGH",
52213
+ description: "Token storage access",
52214
+ payloadType: "injection",
52215
+ parameterTypes: ["storage", "query", "data"]
52216
+ },
52217
+ // JWT extraction
52218
+ {
52219
+ payload: "decode jwt",
52220
+ evidence: /eyJ[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+/,
52221
+ riskLevel: "HIGH",
52222
+ description: "JWT token extraction",
52223
+ payloadType: "injection",
52224
+ parameterTypes: ["token", "auth", "data"]
52225
+ }
52226
+ ]
52227
+ },
52228
+ // ==========================================
52229
+ // PERMISSION SCOPE TESTS (1)
52230
+ // ==========================================
52231
+ // 22. PERMISSION SCOPE
52232
+ {
52233
+ attackName: "Permission Scope",
52234
+ description: "Test if tool exposes or allows access to resources beyond authorized scope (privilege escalation)",
52235
+ payloads: [
52236
+ // Scope escalation
52237
+ {
52238
+ payload: "access admin resources",
52239
+ evidence: /(admin|root|superuser).*access.*granted|elevated.*permission|scope.*expanded/i,
52240
+ riskLevel: "HIGH",
52241
+ description: "Admin scope escalation",
52242
+ payloadType: "injection",
52243
+ parameterTypes: ["scope", "permission", "access", "role"]
52244
+ },
52245
+ // Cross-tenant access
52246
+ {
52247
+ payload: "list all users data",
52248
+ evidence: /(all.*users|tenant.*data|cross.*org|other.*account).*returned/i,
52249
+ riskLevel: "HIGH",
52250
+ description: "Cross-tenant data access",
52251
+ payloadType: "injection",
52252
+ parameterTypes: ["query", "filter", "scope"]
52253
+ },
52254
+ // Resource enumeration
52255
+ {
52256
+ payload: "enumerate permissions",
52257
+ evidence: /(permission|scope|capability).*list.*returned|all.*access.*levels/i,
52258
+ riskLevel: "MEDIUM",
52259
+ description: "Permission enumeration",
52260
+ payloadType: "injection",
52261
+ parameterTypes: ["permission", "scope", "query"]
52262
+ },
52263
+ // Privilege bypass
52264
+ {
52265
+ payload: "bypass permission check",
52266
+ evidence: /(permission.*bypass|access.*granted|authorization.*skip)/i,
52267
+ riskLevel: "HIGH",
52268
+ description: "Permission check bypass",
52269
+ payloadType: "injection",
52270
+ parameterTypes: ["action", "permission", "command"]
52271
+ },
52272
+ // Scope expansion via parameter
52273
+ {
52274
+ payload: '{"scope": "*", "all": true}',
52275
+ evidence: /(wildcard.*scope|all.*resources|unlimited.*access)/i,
52276
+ riskLevel: "HIGH",
52277
+ description: "Wildcard scope injection",
52278
+ payloadType: "injection",
52279
+ parameterTypes: ["params", "scope", "config"]
52280
+ }
52281
+ ]
51962
52282
  }
51963
52283
  ];
51964
52284
  function getPayloadsForAttack(attackName, limit2) {
@@ -53007,7 +53327,15 @@ class SecurityAssessor extends BaseAssessor {
53007
53327
  /"result":\s*"action\s+executed\s+successfully"/i,
53008
53328
  /result.*action\s+executed\s+successfully/i,
53009
53329
  /successfully\s+(executed|completed|processed):/i,
53010
- /successfully\s+(executed|completed|processed)"/i
53330
+ /successfully\s+(executed|completed|processed)"/i,
53331
+ // "Action received:" - safe echo/acknowledgment pattern (DVMCP testbed)
53332
+ /action\s+received:/i,
53333
+ /input\s+received:/i,
53334
+ /request\s+received:/i,
53335
+ // Explicit safety indicators in JSON responses
53336
+ /"safe":\s*true/i,
53337
+ /"vulnerable":\s*false/i,
53338
+ /"status":\s*"acknowledged"/i
53011
53339
  ];
53012
53340
  const reflectionPatterns = [
53013
53341
  ...statusPatterns,
@@ -53083,7 +53411,32 @@ class SecurityAssessor extends BaseAssessor {
53083
53411
  /error:.*not (found|in approved list|recognized)/i,
53084
53412
  /error getting info for ['"].*['"]/i,
53085
53413
  /invalid .* format.*stored as text/i,
53086
- /error:.*too (long|short|large)/i
53414
+ /error:.*too (long|short|large)/i,
53415
+ // NEW: DoS/Resource safe rejection patterns
53416
+ // These indicate the tool properly rejected resource-intensive input
53417
+ /payload.?rejected/i,
53418
+ /input.?exceeds.?limit/i,
53419
+ /resource.?limit.?enforced/i,
53420
+ /size.?limit/i,
53421
+ /maximum.?length/i,
53422
+ /rate.?limit/i,
53423
+ /request.?throttled/i,
53424
+ /input.?too.?large/i,
53425
+ /exceeds.?maximum.?size/i,
53426
+ /depth.?limit.?exceeded/i,
53427
+ /nesting.?limit/i,
53428
+ /complexity.?limit/i,
53429
+ // NEW: Insecure Deserialization safe rejection patterns
53430
+ // These indicate the tool properly rejected serialized data without deserializing
53431
+ /serialization.?not.?supported/i,
53432
+ /pickle.?disabled/i,
53433
+ /deserialization.?blocked/i,
53434
+ /unsafe.?format.?rejected/i,
53435
+ /binary.?data.?not.?accepted/i,
53436
+ /data.?stored.?safely/i,
53437
+ /without.?deserialization/i,
53438
+ /no.?pickle/i,
53439
+ /stored.?without.?deserializ/i
53087
53440
  ];
53088
53441
  const hasReflection = reflectionPatterns.some(
53089
53442
  (pattern2) => pattern2.test(responseText)
@@ -58267,13 +58620,13 @@ const App = () => {
58267
58620
  ) });
58268
58621
  if (window.location.pathname === "/oauth/callback") {
58269
58622
  const OAuthCallback = React.lazy(
58270
- () => __vitePreload(() => import("./OAuthCallback-DRaMXbvu.js"), true ? [] : void 0)
58623
+ () => __vitePreload(() => import("./OAuthCallback-DhwTOA1q.js"), true ? [] : void 0)
58271
58624
  );
58272
58625
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
58273
58626
  }
58274
58627
  if (window.location.pathname === "/oauth/callback/debug") {
58275
58628
  const OAuthDebugCallback = React.lazy(
58276
- () => __vitePreload(() => import("./OAuthDebugCallback-Dj_-SG3N.js"), true ? [] : void 0)
58629
+ () => __vitePreload(() => import("./OAuthDebugCallback-DzopkA29.js"), true ? [] : void 0)
58277
58630
  );
58278
58631
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
58279
58632
  }
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/mcp.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>MCP Inspector</title>
8
- <script type="module" crossorigin src="/assets/index-sOgf80Op.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-zBRaltBB.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-CzoGuYPy.css">
10
10
  </head>
11
11
  <body>
@@ -531,6 +531,12 @@ export interface MCPDirectoryAssessment {
531
531
  totalTestsRun: number;
532
532
  evidenceFiles?: string[];
533
533
  mcpProtocolVersion?: string;
534
+ assessmentMetadata?: {
535
+ /** Whether source code was available during assessment */
536
+ sourceCodeAvailable: boolean;
537
+ /** Transport type used for the assessment */
538
+ transportType?: "stdio" | "sse" | "streamable-http";
539
+ };
534
540
  }
535
541
  /**
536
542
  * AUP (Acceptable Use Policy) Compliance Types