@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 +51 -14
- package/client/dist/assets/{OAuthCallback-DRaMXbvu.js → OAuthCallback-DhwTOA1q.js} +1 -1
- package/client/dist/assets/{OAuthDebugCallback-Dj_-SG3N.js → OAuthDebugCallback-DzopkA29.js} +1 -1
- package/client/dist/assets/{index-sOgf80Op.js → index-zBRaltBB.js} +359 -6
- package/client/dist/index.html +1 -1
- package/client/lib/lib/assessmentTypes.d.ts +6 -0
- package/client/lib/lib/assessmentTypes.d.ts.map +1 -1
- package/client/lib/lib/securityPatterns.d.ts +6 -2
- package/client/lib/lib/securityPatterns.d.ts.map +1 -1
- package/client/lib/lib/securityPatterns.js +326 -2
- package/client/lib/services/assessment/AssessmentOrchestrator.d.ts.map +1 -1
- package/client/lib/services/assessment/AssessmentOrchestrator.js +4 -0
- package/client/lib/services/assessment/PolicyComplianceGenerator.d.ts.map +1 -1
- package/client/lib/services/assessment/PolicyComplianceGenerator.js +15 -0
- package/client/lib/services/assessment/modules/SecurityAssessor.d.ts +3 -1
- package/client/lib/services/assessment/modules/SecurityAssessor.d.ts.map +1 -1
- package/client/lib/services/assessment/modules/SecurityAssessor.js +36 -1
- package/package.json +7 -5
- package/server/build/index.js +27 -0
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 (
|
|
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-
|
|
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);
|
package/client/dist/assets/{OAuthDebugCallback-Dj_-SG3N.js → OAuthDebugCallback-DzopkA29.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-
|
|
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.
|
|
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.
|
|
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-
|
|
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-
|
|
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
|
}
|
package/client/dist/index.html
CHANGED
|
@@ -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-
|
|
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
|