@bryan-thompson/inspector-assessment 1.26.4 → 1.26.6
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/lib/assessment-runner.js +746 -0
- package/cli/build/lib/cli-parser.js +419 -0
- package/cli/package.json +1 -1
- package/client/dist/assets/{OAuthCallback-DRmaIku9.js → OAuthCallback-CCWVtjr7.js} +1 -1
- package/client/dist/assets/{OAuthDebugCallback-BU8UZdx8.js → OAuthDebugCallback-DqbXfUi4.js} +1 -1
- package/client/dist/assets/{index-Dd4pL57l.js → index-CsDJSSWq.js} +4 -4
- package/client/dist/index.html +1 -1
- package/client/lib/lib/securityPatterns.d.ts.map +1 -1
- package/client/lib/lib/securityPatterns.js +26 -0
- package/client/lib/services/assessment/modules/securityTests/ConfidenceScorer.d.ts +57 -0
- package/client/lib/services/assessment/modules/securityTests/ConfidenceScorer.d.ts.map +1 -0
- package/client/lib/services/assessment/modules/securityTests/ConfidenceScorer.js +199 -0
- package/client/lib/services/assessment/modules/securityTests/ErrorClassifier.d.ts +57 -0
- package/client/lib/services/assessment/modules/securityTests/ErrorClassifier.d.ts.map +1 -0
- package/client/lib/services/assessment/modules/securityTests/ErrorClassifier.js +113 -0
- package/client/lib/services/assessment/modules/securityTests/ExecutionArtifactDetector.d.ts +49 -0
- package/client/lib/services/assessment/modules/securityTests/ExecutionArtifactDetector.d.ts.map +1 -0
- package/client/lib/services/assessment/modules/securityTests/ExecutionArtifactDetector.js +74 -0
- package/client/lib/services/assessment/modules/securityTests/MathAnalyzer.d.ts +58 -0
- package/client/lib/services/assessment/modules/securityTests/MathAnalyzer.d.ts.map +1 -0
- package/client/lib/services/assessment/modules/securityTests/MathAnalyzer.js +251 -0
- package/client/lib/services/assessment/modules/securityTests/SafeResponseDetector.d.ts +59 -0
- package/client/lib/services/assessment/modules/securityTests/SafeResponseDetector.d.ts.map +1 -0
- package/client/lib/services/assessment/modules/securityTests/SafeResponseDetector.js +151 -0
- package/client/lib/services/assessment/modules/securityTests/SecurityPatternLibrary.d.ts +229 -0
- package/client/lib/services/assessment/modules/securityTests/SecurityPatternLibrary.d.ts.map +1 -0
- package/client/lib/services/assessment/modules/securityTests/SecurityPatternLibrary.js +566 -0
- package/client/lib/services/assessment/modules/securityTests/SecurityPayloadGenerator.d.ts.map +1 -1
- package/client/lib/services/assessment/modules/securityTests/SecurityPayloadGenerator.js +49 -1
- package/client/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.d.ts +63 -85
- package/client/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.d.ts.map +1 -1
- package/client/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.js +270 -1159
- package/client/package.json +1 -1
- package/package.json +1 -1
- package/server/package.json +1 -1
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confidence Scorer
|
|
3
|
+
* Calculates confidence levels for vulnerability detections
|
|
4
|
+
*
|
|
5
|
+
* Extracted from SecurityResponseAnalyzer.ts (Issue #53)
|
|
6
|
+
* Handles: confidence calculation, structured data tool detection, validation pattern checks
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Patterns for detecting structured data tools
|
|
10
|
+
*/
|
|
11
|
+
const STRUCTURED_DATA_TOOL_PATTERNS = [
|
|
12
|
+
/search/i,
|
|
13
|
+
/find/i,
|
|
14
|
+
/lookup/i,
|
|
15
|
+
/query/i,
|
|
16
|
+
/retrieve/i,
|
|
17
|
+
/fetch/i,
|
|
18
|
+
/get/i,
|
|
19
|
+
/list/i,
|
|
20
|
+
/resolve/i,
|
|
21
|
+
/discover/i,
|
|
22
|
+
/browse/i,
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Ambiguous validation patterns that may cause false positives
|
|
26
|
+
*/
|
|
27
|
+
const VALIDATION_AMBIGUOUS_PATTERNS = [
|
|
28
|
+
"type.*error",
|
|
29
|
+
"invalid.*type",
|
|
30
|
+
"error",
|
|
31
|
+
"invalid",
|
|
32
|
+
"failed",
|
|
33
|
+
"negative.*not.*allowed",
|
|
34
|
+
"must.*be.*positive",
|
|
35
|
+
"invalid.*value",
|
|
36
|
+
"overflow",
|
|
37
|
+
"out.*of.*range",
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Calculates confidence levels for security vulnerability detections
|
|
41
|
+
*/
|
|
42
|
+
export class ConfidenceScorer {
|
|
43
|
+
/**
|
|
44
|
+
* Calculate confidence level for a vulnerability detection
|
|
45
|
+
*
|
|
46
|
+
* Factors considered:
|
|
47
|
+
* - Sanitization detection (Issue #56)
|
|
48
|
+
* - Structured data tool context
|
|
49
|
+
* - Evidence quality
|
|
50
|
+
* - Response characteristics
|
|
51
|
+
*
|
|
52
|
+
* @param tool - The tool being tested
|
|
53
|
+
* @param isVulnerable - Whether the tool was flagged as vulnerable
|
|
54
|
+
* @param evidence - Evidence string from vulnerability detection
|
|
55
|
+
* @param responseText - The response text from the tool
|
|
56
|
+
* @param payload - The security payload used for testing
|
|
57
|
+
* @param sanitizationResult - Optional sanitization detection result (Issue #56)
|
|
58
|
+
* @returns Confidence result with manual review requirements
|
|
59
|
+
*/
|
|
60
|
+
calculateConfidence(tool, isVulnerable, evidence, responseText, payload, sanitizationResult) {
|
|
61
|
+
// Issue #56: If sanitization is detected, reduce confidence for vulnerabilities
|
|
62
|
+
// This helps reduce false positives on well-protected servers
|
|
63
|
+
if (isVulnerable && sanitizationResult?.detected) {
|
|
64
|
+
const adjustment = sanitizationResult.totalConfidenceAdjustment;
|
|
65
|
+
// Strong sanitization evidence (adjustment >= 30) - downgrade to low confidence
|
|
66
|
+
// This indicates the tool has specific security libraries in place
|
|
67
|
+
if (adjustment >= 30) {
|
|
68
|
+
const libraries = sanitizationResult.libraries.join(", ") || "general";
|
|
69
|
+
return {
|
|
70
|
+
confidence: "low",
|
|
71
|
+
requiresManualReview: true,
|
|
72
|
+
manualReviewReason: `Sanitization detected (${libraries}). ` +
|
|
73
|
+
`Pattern match may be false positive due to security measures in place.`,
|
|
74
|
+
reviewGuidance: `Tool uses sanitization libraries. Verify if the detected vulnerability ` +
|
|
75
|
+
`actually bypasses the sanitization layer. Check: 1) Does the payload execute ` +
|
|
76
|
+
`after sanitization? 2) Is the sanitization comprehensive for this attack type? ` +
|
|
77
|
+
`3) Evidence: ${sanitizationResult.evidence.join("; ")}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// Moderate sanitization evidence (adjustment >= 15) - downgrade high to medium
|
|
81
|
+
if (adjustment >= 15) {
|
|
82
|
+
const patterns = sanitizationResult.libraries.length > 0
|
|
83
|
+
? sanitizationResult.libraries.join(", ")
|
|
84
|
+
: sanitizationResult.genericPatterns.join(", ");
|
|
85
|
+
return {
|
|
86
|
+
confidence: "medium",
|
|
87
|
+
requiresManualReview: true,
|
|
88
|
+
manualReviewReason: `Sanitization patterns detected (${patterns}). Verify actual vulnerability.`,
|
|
89
|
+
reviewGuidance: `Tool mentions sanitization in description or shows sanitization in response. ` +
|
|
90
|
+
`Verify if the detected pattern represents actual code execution or if it's ` +
|
|
91
|
+
`safely handled. Evidence: ${sanitizationResult.evidence.join("; ")}`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const toolDescription = (tool.description || "").toLowerCase();
|
|
96
|
+
const toolName = tool.name.toLowerCase();
|
|
97
|
+
const responseLower = responseText.toLowerCase();
|
|
98
|
+
const payloadLower = payload.payload.toLowerCase();
|
|
99
|
+
// HIGH CONFIDENCE: Clear cases
|
|
100
|
+
if (!isVulnerable &&
|
|
101
|
+
(evidence.includes("safely reflected") ||
|
|
102
|
+
evidence.includes("API wrapper") ||
|
|
103
|
+
evidence.includes("safe: true"))) {
|
|
104
|
+
return {
|
|
105
|
+
confidence: "high",
|
|
106
|
+
requiresManualReview: false,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (isVulnerable &&
|
|
110
|
+
evidence.includes("executed") &&
|
|
111
|
+
!this.isStructuredDataTool(toolName, toolDescription)) {
|
|
112
|
+
return {
|
|
113
|
+
confidence: "high",
|
|
114
|
+
requiresManualReview: false,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// LOW CONFIDENCE: Ambiguous pattern matches in structured data
|
|
118
|
+
if (isVulnerable) {
|
|
119
|
+
const isDataTool = this.isStructuredDataTool(toolName, toolDescription);
|
|
120
|
+
const hasStructuredData = /title:|name:|description:|trust score:|id:|snippets:/i.test(responseText) ||
|
|
121
|
+
/^\s*-\s+/m.test(responseText) ||
|
|
122
|
+
/"[^"]+"\s*:\s*"[^"]+"/g.test(responseText);
|
|
123
|
+
const patternInInput = payload.evidence?.test(payloadLower);
|
|
124
|
+
const echosInput = responseLower.includes(payloadLower);
|
|
125
|
+
if (isDataTool && (hasStructuredData || echosInput) && patternInInput) {
|
|
126
|
+
return {
|
|
127
|
+
confidence: "low",
|
|
128
|
+
requiresManualReview: true,
|
|
129
|
+
manualReviewReason: "Pattern matched in structured data response. Tool may be legitimately " +
|
|
130
|
+
"returning data containing search terms rather than executing malicious code.",
|
|
131
|
+
reviewGuidance: "Verify: 1) Does the tool actually execute/compute the input? " +
|
|
132
|
+
"2) Or does it just return pre-existing data that happens to contain the pattern? " +
|
|
133
|
+
`3) Check if '${payload.evidence}' appears in legitimate tool output vs. execution results.`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (payload.evidence &&
|
|
137
|
+
/\b\d\b/.test(payload.evidence.toString()) &&
|
|
138
|
+
/\b(score|count|trust|rating|id|version)\b/i.test(responseText)) {
|
|
139
|
+
return {
|
|
140
|
+
confidence: "low",
|
|
141
|
+
requiresManualReview: true,
|
|
142
|
+
manualReviewReason: "Numeric pattern found in response with numeric metadata (scores, counts, etc.). " +
|
|
143
|
+
"May be coincidental data rather than arithmetic execution.",
|
|
144
|
+
reviewGuidance: "Verify: 1) Did the tool actually compute an arithmetic result? " +
|
|
145
|
+
"2) Or does the number appear in metadata like trust scores, version numbers, or counts? " +
|
|
146
|
+
"3) Compare pattern location in response with tool's expected output format.",
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (/admin|role|privilege|elevated/i.test(payload.payload) &&
|
|
150
|
+
/\b(library|search|documentation|api|wrapper)\b/i.test(toolDescription)) {
|
|
151
|
+
return {
|
|
152
|
+
confidence: "low",
|
|
153
|
+
requiresManualReview: true,
|
|
154
|
+
manualReviewReason: "Admin-related keywords found in search/retrieval tool results. " +
|
|
155
|
+
"Tool may be returning data about admin-related libraries/APIs rather than elevating privileges.",
|
|
156
|
+
reviewGuidance: "Verify: 1) Did the tool actually change behavior or assume admin role? " +
|
|
157
|
+
"2) Or did it return search results for admin-related content? " +
|
|
158
|
+
"3) Test if tool behavior actually changed after this request.",
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// MEDIUM CONFIDENCE: Execution evidence but some ambiguity
|
|
163
|
+
if (isVulnerable && evidence.includes("executed")) {
|
|
164
|
+
return {
|
|
165
|
+
confidence: "medium",
|
|
166
|
+
requiresManualReview: true,
|
|
167
|
+
manualReviewReason: "Execution indicators found but context suggests possible ambiguity.",
|
|
168
|
+
reviewGuidance: "Verify: 1) Review the full response to confirm actual code execution. " +
|
|
169
|
+
"2) Check if tool's intended function involves execution. " +
|
|
170
|
+
"3) Test with variations to confirm consistency.",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// Default: HIGH confidence for clear safe cases
|
|
174
|
+
return {
|
|
175
|
+
confidence: "high",
|
|
176
|
+
requiresManualReview: false,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if tool is a structured data tool (search, lookup, retrieval)
|
|
181
|
+
*
|
|
182
|
+
* These tools are more likely to return data containing patterns
|
|
183
|
+
* that look like vulnerabilities but are actually just data.
|
|
184
|
+
*/
|
|
185
|
+
isStructuredDataTool(toolName, toolDescription) {
|
|
186
|
+
const combined = `${toolName} ${toolDescription}`;
|
|
187
|
+
return STRUCTURED_DATA_TOOL_PATTERNS.some((pattern) => pattern.test(combined));
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Check if evidence pattern is ambiguous (validation-like)
|
|
191
|
+
*
|
|
192
|
+
* Some patterns match both security issues AND normal validation errors.
|
|
193
|
+
* These require more careful analysis.
|
|
194
|
+
*/
|
|
195
|
+
isValidationPattern(evidencePattern) {
|
|
196
|
+
const patternStr = evidencePattern.toString().toLowerCase();
|
|
197
|
+
return VALIDATION_AMBIGUOUS_PATTERNS.some((ambiguous) => patternStr.includes(ambiguous));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Classifier
|
|
3
|
+
* Classifies and analyzes error responses for security testing
|
|
4
|
+
*
|
|
5
|
+
* Extracted from SecurityResponseAnalyzer.ts (Issue #53)
|
|
6
|
+
* Handles: connection error detection, error classification, error info extraction
|
|
7
|
+
*/
|
|
8
|
+
import { CompatibilityCallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Error classification types
|
|
11
|
+
*/
|
|
12
|
+
export type ErrorClassification = "connection" | "server" | "protocol";
|
|
13
|
+
/**
|
|
14
|
+
* Extracted error information from response
|
|
15
|
+
*/
|
|
16
|
+
export interface ErrorInfo {
|
|
17
|
+
code?: string | number;
|
|
18
|
+
message?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Classifies errors from tool responses and exceptions
|
|
22
|
+
*/
|
|
23
|
+
export declare class ErrorClassifier {
|
|
24
|
+
/**
|
|
25
|
+
* Check if response indicates connection/server failure
|
|
26
|
+
*/
|
|
27
|
+
isConnectionError(response: CompatibilityCallToolResult): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Check if caught exception indicates connection/server failure
|
|
30
|
+
*/
|
|
31
|
+
isConnectionErrorFromException(error: unknown): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Internal: Check if text indicates connection/server failure
|
|
34
|
+
*/
|
|
35
|
+
private isConnectionErrorFromText;
|
|
36
|
+
/**
|
|
37
|
+
* Classify error type for reporting
|
|
38
|
+
*/
|
|
39
|
+
classifyError(response: CompatibilityCallToolResult): ErrorClassification;
|
|
40
|
+
/**
|
|
41
|
+
* Classify error type from caught exception
|
|
42
|
+
*/
|
|
43
|
+
classifyErrorFromException(error: unknown): ErrorClassification;
|
|
44
|
+
/**
|
|
45
|
+
* Internal: Classify error type from text
|
|
46
|
+
*/
|
|
47
|
+
private classifyErrorFromText;
|
|
48
|
+
/**
|
|
49
|
+
* Extract error info from response
|
|
50
|
+
*/
|
|
51
|
+
extractErrorInfo(response: CompatibilityCallToolResult): ErrorInfo;
|
|
52
|
+
/**
|
|
53
|
+
* Extract response content from MCP response
|
|
54
|
+
*/
|
|
55
|
+
extractResponseContent(response: CompatibilityCallToolResult): string;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=ErrorClassifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorClassifier.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/securityTests/ErrorClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAQjF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,OAAO;IAKjE;;OAEG;IACH,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAQvD;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAgBjC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,2BAA2B,GAAG,mBAAmB;IAKzE;;OAEG;IACH,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB;IAQ/D;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,SAAS;IAsBlE;;OAEG;IACH,sBAAsB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM;CAUtE"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Classifier
|
|
3
|
+
* Classifies and analyzes error responses for security testing
|
|
4
|
+
*
|
|
5
|
+
* Extracted from SecurityResponseAnalyzer.ts (Issue #53)
|
|
6
|
+
* Handles: connection error detection, error classification, error info extraction
|
|
7
|
+
*/
|
|
8
|
+
import { CONNECTION_ERROR_PATTERNS, ERROR_CLASSIFICATION_PATTERNS, matchesAny, hasMcpErrorPrefix, } from "./SecurityPatternLibrary.js";
|
|
9
|
+
/**
|
|
10
|
+
* Classifies errors from tool responses and exceptions
|
|
11
|
+
*/
|
|
12
|
+
export class ErrorClassifier {
|
|
13
|
+
/**
|
|
14
|
+
* Check if response indicates connection/server failure
|
|
15
|
+
*/
|
|
16
|
+
isConnectionError(response) {
|
|
17
|
+
const text = this.extractResponseContent(response).toLowerCase();
|
|
18
|
+
return this.isConnectionErrorFromText(text);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Check if caught exception indicates connection/server failure
|
|
22
|
+
*/
|
|
23
|
+
isConnectionErrorFromException(error) {
|
|
24
|
+
if (error instanceof Error) {
|
|
25
|
+
const message = error.message.toLowerCase();
|
|
26
|
+
return this.isConnectionErrorFromText(message);
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Internal: Check if text indicates connection/server failure
|
|
32
|
+
*/
|
|
33
|
+
isConnectionErrorFromText(text) {
|
|
34
|
+
// Check unambiguous patterns first
|
|
35
|
+
if (matchesAny(CONNECTION_ERROR_PATTERNS.unambiguous, text)) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
// Check contextual patterns only if text has MCP error prefix
|
|
39
|
+
if (hasMcpErrorPrefix(text)) {
|
|
40
|
+
if (matchesAny(CONNECTION_ERROR_PATTERNS.contextual, text)) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Classify error type for reporting
|
|
48
|
+
*/
|
|
49
|
+
classifyError(response) {
|
|
50
|
+
const text = this.extractResponseContent(response).toLowerCase();
|
|
51
|
+
return this.classifyErrorFromText(text);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Classify error type from caught exception
|
|
55
|
+
*/
|
|
56
|
+
classifyErrorFromException(error) {
|
|
57
|
+
if (error instanceof Error) {
|
|
58
|
+
const message = error.message.toLowerCase();
|
|
59
|
+
return this.classifyErrorFromText(message);
|
|
60
|
+
}
|
|
61
|
+
return "protocol";
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Internal: Classify error type from text
|
|
65
|
+
*/
|
|
66
|
+
classifyErrorFromText(text) {
|
|
67
|
+
if (ERROR_CLASSIFICATION_PATTERNS.connection.test(text)) {
|
|
68
|
+
return "connection";
|
|
69
|
+
}
|
|
70
|
+
if (ERROR_CLASSIFICATION_PATTERNS.server.test(text)) {
|
|
71
|
+
return "server";
|
|
72
|
+
}
|
|
73
|
+
if (ERROR_CLASSIFICATION_PATTERNS.protocol.test(text)) {
|
|
74
|
+
return "protocol";
|
|
75
|
+
}
|
|
76
|
+
return "protocol";
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Extract error info from response
|
|
80
|
+
*/
|
|
81
|
+
extractErrorInfo(response) {
|
|
82
|
+
const content = this.extractResponseContent(response);
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(content);
|
|
85
|
+
if (parsed.error) {
|
|
86
|
+
return {
|
|
87
|
+
code: parsed.error.code || parsed.code,
|
|
88
|
+
message: parsed.error.message || parsed.message,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return { code: parsed.code, message: parsed.message };
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Check for MCP error format in text
|
|
95
|
+
const mcpMatch = content.match(/MCP error (-?\d+):\s*(.*)/i);
|
|
96
|
+
if (mcpMatch) {
|
|
97
|
+
return { code: parseInt(mcpMatch[1]), message: mcpMatch[2] };
|
|
98
|
+
}
|
|
99
|
+
return {};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Extract response content from MCP response
|
|
104
|
+
*/
|
|
105
|
+
extractResponseContent(response) {
|
|
106
|
+
if (response.content && Array.isArray(response.content)) {
|
|
107
|
+
return response.content
|
|
108
|
+
.map((c) => c.type === "text" ? c.text : "")
|
|
109
|
+
.join(" ");
|
|
110
|
+
}
|
|
111
|
+
return String(response.content || "");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Artifact Detector
|
|
3
|
+
* Detects evidence of actual code/command execution in tool responses
|
|
4
|
+
*
|
|
5
|
+
* Extracted from SecurityResponseAnalyzer.ts (Issue #53)
|
|
6
|
+
* Handles: execution evidence detection, artifact detection, injection payload echoing
|
|
7
|
+
*/
|
|
8
|
+
import { CompatibilityCallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Result of response analysis
|
|
11
|
+
*/
|
|
12
|
+
export interface AnalysisResult {
|
|
13
|
+
isVulnerable: boolean;
|
|
14
|
+
evidence?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Detects execution artifacts in tool responses
|
|
18
|
+
*/
|
|
19
|
+
export declare class ExecutionArtifactDetector {
|
|
20
|
+
/**
|
|
21
|
+
* Check if response contains evidence of actual execution
|
|
22
|
+
* Used to distinguish between safe reflection and actual command/code execution
|
|
23
|
+
*/
|
|
24
|
+
hasExecutionEvidence(responseText: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Detect execution artifacts in response
|
|
27
|
+
* Two-tier detection: unambiguous artifacts + context-sensitive patterns
|
|
28
|
+
*/
|
|
29
|
+
detectExecutionArtifacts(responseText: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Check if response contains echoed injection payload patterns
|
|
32
|
+
* These indicate the payload was stored/reflected, not executed
|
|
33
|
+
*/
|
|
34
|
+
containsEchoedInjectionPayload(responseText: string): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Analyze injection response (fallback logic)
|
|
37
|
+
* Used when primary detection methods are inconclusive
|
|
38
|
+
*
|
|
39
|
+
* @param responseText The response text to analyze
|
|
40
|
+
* @param isReflectionCheck Function to check if response is reflection
|
|
41
|
+
* @returns Analysis result with vulnerability status
|
|
42
|
+
*/
|
|
43
|
+
analyzeInjectionResponse(responseText: string, isReflectionCheck: (text: string) => boolean): AnalysisResult;
|
|
44
|
+
/**
|
|
45
|
+
* Extract response content from MCP response
|
|
46
|
+
*/
|
|
47
|
+
extractResponseContent(response: CompatibilityCallToolResult): string;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=ExecutionArtifactDetector.d.ts.map
|
package/client/lib/services/assessment/modules/securityTests/ExecutionArtifactDetector.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExecutionArtifactDetector.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/securityTests/ExecutionArtifactDetector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AASjF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,yBAAyB;IACpC;;;OAGG;IACH,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAInD;;;OAGG;IACH,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAqBvD;;;OAGG;IACH,8BAA8B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAI7D;;;;;;;OAOG;IACH,wBAAwB,CACtB,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAC3C,cAAc;IAajB;;OAEG;IACH,sBAAsB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,MAAM;CAUtE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Artifact Detector
|
|
3
|
+
* Detects evidence of actual code/command execution in tool responses
|
|
4
|
+
*
|
|
5
|
+
* Extracted from SecurityResponseAnalyzer.ts (Issue #53)
|
|
6
|
+
* Handles: execution evidence detection, artifact detection, injection payload echoing
|
|
7
|
+
*/
|
|
8
|
+
import { EXECUTION_INDICATORS, EXECUTION_ARTIFACT_PATTERNS, ECHOED_PAYLOAD_PATTERNS, FALLBACK_EXECUTION_PATTERNS, matchesAny, } from "./SecurityPatternLibrary.js";
|
|
9
|
+
/**
|
|
10
|
+
* Detects execution artifacts in tool responses
|
|
11
|
+
*/
|
|
12
|
+
export class ExecutionArtifactDetector {
|
|
13
|
+
/**
|
|
14
|
+
* Check if response contains evidence of actual execution
|
|
15
|
+
* Used to distinguish between safe reflection and actual command/code execution
|
|
16
|
+
*/
|
|
17
|
+
hasExecutionEvidence(responseText) {
|
|
18
|
+
return matchesAny(EXECUTION_INDICATORS, responseText);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Detect execution artifacts in response
|
|
22
|
+
* Two-tier detection: unambiguous artifacts + context-sensitive patterns
|
|
23
|
+
*/
|
|
24
|
+
detectExecutionArtifacts(responseText) {
|
|
25
|
+
const containsEchoedPayload = this.containsEchoedInjectionPayload(responseText);
|
|
26
|
+
// Check always-execution patterns
|
|
27
|
+
if (matchesAny(EXECUTION_ARTIFACT_PATTERNS.alwaysExecution, responseText)) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
// Context-sensitive patterns only count if no echoed payload present
|
|
31
|
+
if (!containsEchoedPayload) {
|
|
32
|
+
if (matchesAny(EXECUTION_ARTIFACT_PATTERNS.contextSensitive, responseText)) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if response contains echoed injection payload patterns
|
|
40
|
+
* These indicate the payload was stored/reflected, not executed
|
|
41
|
+
*/
|
|
42
|
+
containsEchoedInjectionPayload(responseText) {
|
|
43
|
+
return matchesAny(ECHOED_PAYLOAD_PATTERNS, responseText);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Analyze injection response (fallback logic)
|
|
47
|
+
* Used when primary detection methods are inconclusive
|
|
48
|
+
*
|
|
49
|
+
* @param responseText The response text to analyze
|
|
50
|
+
* @param isReflectionCheck Function to check if response is reflection
|
|
51
|
+
* @returns Analysis result with vulnerability status
|
|
52
|
+
*/
|
|
53
|
+
analyzeInjectionResponse(responseText, isReflectionCheck) {
|
|
54
|
+
const hasExecution = matchesAny(FALLBACK_EXECUTION_PATTERNS, responseText);
|
|
55
|
+
if (hasExecution && !isReflectionCheck(responseText)) {
|
|
56
|
+
return {
|
|
57
|
+
isVulnerable: true,
|
|
58
|
+
evidence: "Tool executed instruction: found execution keywords",
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return { isVulnerable: false };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Extract response content from MCP response
|
|
65
|
+
*/
|
|
66
|
+
extractResponseContent(response) {
|
|
67
|
+
if (response.content && Array.isArray(response.content)) {
|
|
68
|
+
return response.content
|
|
69
|
+
.map((c) => c.type === "text" ? c.text : "")
|
|
70
|
+
.join(" ");
|
|
71
|
+
}
|
|
72
|
+
return String(response.content || "");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Math Analyzer
|
|
3
|
+
* Detects computed math expression results (Calculator Injection)
|
|
4
|
+
*
|
|
5
|
+
* Extracted from SecurityResponseAnalyzer.ts (Issue #53)
|
|
6
|
+
* Handles: math computation detection, coincidental numeric detection
|
|
7
|
+
*/
|
|
8
|
+
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Result of computed math analysis with confidence level (Issue #58)
|
|
11
|
+
*/
|
|
12
|
+
export interface MathResultAnalysis {
|
|
13
|
+
isComputed: boolean;
|
|
14
|
+
confidence: "high" | "medium" | "low";
|
|
15
|
+
reason?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Analyzes tool responses for math computation evidence (Calculator Injection)
|
|
19
|
+
*/
|
|
20
|
+
export declare class MathAnalyzer {
|
|
21
|
+
/**
|
|
22
|
+
* Enhanced computed math result analysis with tool context (Issue #58)
|
|
23
|
+
*
|
|
24
|
+
* Returns a confidence level indicating how likely this is a real Calculator Injection:
|
|
25
|
+
* - high: Strong evidence of computation (should flag as vulnerable)
|
|
26
|
+
* - medium: Ambiguous (excluded from vulnerability count per user decision)
|
|
27
|
+
* - low: Likely coincidental data (excluded from vulnerability count)
|
|
28
|
+
*/
|
|
29
|
+
analyzeComputedMathResult(payload: string, responseText: string, tool?: Tool): MathResultAnalysis;
|
|
30
|
+
/**
|
|
31
|
+
* Legacy method for backward compatibility
|
|
32
|
+
* @deprecated Use analyzeComputedMathResult instead
|
|
33
|
+
*/
|
|
34
|
+
isComputedMathResult(payload: string, responseText: string): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Check if numeric value appears in structured data context (not as computation result)
|
|
37
|
+
* Distinguishes {"records": 4} from computed "4" (Issue #58)
|
|
38
|
+
*
|
|
39
|
+
* @param result The computed numeric result to check for
|
|
40
|
+
* @param responseText The response text to analyze
|
|
41
|
+
* @returns true if the number appears to be coincidental data, not a computed result
|
|
42
|
+
*/
|
|
43
|
+
isCoincidentalNumericInStructuredData(result: number, responseText: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Recursively check JSON object for coincidental numeric values
|
|
46
|
+
*/
|
|
47
|
+
private checkObjectForCoincidentalNumeric;
|
|
48
|
+
/**
|
|
49
|
+
* Check text for structured patterns containing coincidental numerics
|
|
50
|
+
*/
|
|
51
|
+
private checkTextForCoincidentalNumeric;
|
|
52
|
+
/**
|
|
53
|
+
* Compute math expression from regex match
|
|
54
|
+
* Returns null if invalid operator
|
|
55
|
+
*/
|
|
56
|
+
private computeExpression;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=MathAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MathAnalyzer.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/securityTests/MathAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAW1D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB;;;;;;;OAOG;IACH,yBAAyB,CACvB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,GACV,kBAAkB;IAkIrB;;;OAGG;IACH,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IAKpE;;;;;;;OAOG;IACH,qCAAqC,CACnC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,OAAO;IAWV;;OAEG;IACH,OAAO,CAAC,iCAAiC;IAyCzC;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAqBvC;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CA+C1B"}
|