@bryan-thompson/inspector-assessment-client 1.26.5 → 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.
Files changed (28) hide show
  1. package/dist/assets/{OAuthCallback-DpdInvWI.js → OAuthCallback-CCWVtjr7.js} +1 -1
  2. package/dist/assets/{OAuthDebugCallback-D1ImpKK5.js → OAuthDebugCallback-DqbXfUi4.js} +1 -1
  3. package/dist/assets/{index-umcoGmYw.js → index-CsDJSSWq.js} +4 -4
  4. package/dist/index.html +1 -1
  5. package/lib/services/assessment/modules/securityTests/ConfidenceScorer.d.ts +57 -0
  6. package/lib/services/assessment/modules/securityTests/ConfidenceScorer.d.ts.map +1 -0
  7. package/lib/services/assessment/modules/securityTests/ConfidenceScorer.js +199 -0
  8. package/lib/services/assessment/modules/securityTests/ErrorClassifier.d.ts +57 -0
  9. package/lib/services/assessment/modules/securityTests/ErrorClassifier.d.ts.map +1 -0
  10. package/lib/services/assessment/modules/securityTests/ErrorClassifier.js +113 -0
  11. package/lib/services/assessment/modules/securityTests/ExecutionArtifactDetector.d.ts +49 -0
  12. package/lib/services/assessment/modules/securityTests/ExecutionArtifactDetector.d.ts.map +1 -0
  13. package/lib/services/assessment/modules/securityTests/ExecutionArtifactDetector.js +74 -0
  14. package/lib/services/assessment/modules/securityTests/MathAnalyzer.d.ts +58 -0
  15. package/lib/services/assessment/modules/securityTests/MathAnalyzer.d.ts.map +1 -0
  16. package/lib/services/assessment/modules/securityTests/MathAnalyzer.js +251 -0
  17. package/lib/services/assessment/modules/securityTests/SafeResponseDetector.d.ts +59 -0
  18. package/lib/services/assessment/modules/securityTests/SafeResponseDetector.d.ts.map +1 -0
  19. package/lib/services/assessment/modules/securityTests/SafeResponseDetector.js +151 -0
  20. package/lib/services/assessment/modules/securityTests/SecurityPatternLibrary.d.ts +229 -0
  21. package/lib/services/assessment/modules/securityTests/SecurityPatternLibrary.d.ts.map +1 -0
  22. package/lib/services/assessment/modules/securityTests/SecurityPatternLibrary.js +566 -0
  23. package/lib/services/assessment/modules/securityTests/SecurityPayloadGenerator.d.ts.map +1 -1
  24. package/lib/services/assessment/modules/securityTests/SecurityPayloadGenerator.js +49 -24
  25. package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.d.ts +63 -85
  26. package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.d.ts.map +1 -1
  27. package/lib/services/assessment/modules/securityTests/SecurityResponseAnalyzer.js +270 -1171
  28. package/package.json +1 -1
@@ -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-umcoGmYw.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-CsDJSSWq.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-umcoGmYw.js";
1
+ import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-CsDJSSWq.js";
2
2
  const OAuthDebugCallback = ({ onConnect }) => {
3
3
  reactExports.useEffect(() => {
4
4
  let isProcessed = false;
@@ -16373,7 +16373,7 @@ object({
16373
16373
  token_type_hint: string().optional()
16374
16374
  }).strip();
16375
16375
  const name = "@bryan-thompson/inspector-assessment-client";
16376
- const version$1 = "1.26.5";
16376
+ const version$1 = "1.26.6";
16377
16377
  const packageJson = {
16378
16378
  name,
16379
16379
  version: version$1
@@ -45288,7 +45288,7 @@ const useTheme = () => {
45288
45288
  [theme, setThemeWithSideEffect]
45289
45289
  );
45290
45290
  };
45291
- const version = "1.26.5";
45291
+ const version = "1.26.6";
45292
45292
  var [createTooltipContext] = createContextScope("Tooltip", [
45293
45293
  createPopperScope
45294
45294
  ]);
@@ -48845,13 +48845,13 @@ const App = () => {
48845
48845
  ) });
48846
48846
  if (window.location.pathname === "/oauth/callback") {
48847
48847
  const OAuthCallback = React.lazy(
48848
- () => __vitePreload(() => import("./OAuthCallback-DpdInvWI.js"), true ? [] : void 0)
48848
+ () => __vitePreload(() => import("./OAuthCallback-CCWVtjr7.js"), true ? [] : void 0)
48849
48849
  );
48850
48850
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
48851
48851
  }
48852
48852
  if (window.location.pathname === "/oauth/callback/debug") {
48853
48853
  const OAuthDebugCallback = React.lazy(
48854
- () => __vitePreload(() => import("./OAuthDebugCallback-D1ImpKK5.js"), true ? [] : void 0)
48854
+ () => __vitePreload(() => import("./OAuthDebugCallback-DqbXfUi4.js"), true ? [] : void 0)
48855
48855
  );
48856
48856
  return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
48857
48857
  }
package/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-umcoGmYw.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-CsDJSSWq.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-cHhcEXbr.css">
10
10
  </head>
11
11
  <body>
@@ -0,0 +1,57 @@
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
+ import { Tool } from "@modelcontextprotocol/sdk/types.js";
9
+ import { SecurityPayload } from "../../../../lib/securityPatterns.js";
10
+ import type { SanitizationDetectionResult } from "./SanitizationDetector.js";
11
+ /**
12
+ * Result of confidence calculation
13
+ */
14
+ export interface ConfidenceResult {
15
+ confidence: "high" | "medium" | "low";
16
+ requiresManualReview: boolean;
17
+ manualReviewReason?: string;
18
+ reviewGuidance?: string;
19
+ }
20
+ /**
21
+ * Calculates confidence levels for security vulnerability detections
22
+ */
23
+ export declare class ConfidenceScorer {
24
+ /**
25
+ * Calculate confidence level for a vulnerability detection
26
+ *
27
+ * Factors considered:
28
+ * - Sanitization detection (Issue #56)
29
+ * - Structured data tool context
30
+ * - Evidence quality
31
+ * - Response characteristics
32
+ *
33
+ * @param tool - The tool being tested
34
+ * @param isVulnerable - Whether the tool was flagged as vulnerable
35
+ * @param evidence - Evidence string from vulnerability detection
36
+ * @param responseText - The response text from the tool
37
+ * @param payload - The security payload used for testing
38
+ * @param sanitizationResult - Optional sanitization detection result (Issue #56)
39
+ * @returns Confidence result with manual review requirements
40
+ */
41
+ calculateConfidence(tool: Tool, isVulnerable: boolean, evidence: string, responseText: string, payload: SecurityPayload, sanitizationResult?: SanitizationDetectionResult): ConfidenceResult;
42
+ /**
43
+ * Check if tool is a structured data tool (search, lookup, retrieval)
44
+ *
45
+ * These tools are more likely to return data containing patterns
46
+ * that look like vulnerabilities but are actually just data.
47
+ */
48
+ isStructuredDataTool(toolName: string, toolDescription: string): boolean;
49
+ /**
50
+ * Check if evidence pattern is ambiguous (validation-like)
51
+ *
52
+ * Some patterns match both security issues AND normal validation errors.
53
+ * These require more careful analysis.
54
+ */
55
+ isValidationPattern(evidencePattern: RegExp): boolean;
56
+ }
57
+ //# sourceMappingURL=ConfidenceScorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfidenceScorer.d.ts","sourceRoot":"","sources":["../../../../../src/services/assessment/modules/securityTests/ConfidenceScorer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAmCD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B;;;;;;;;;;;;;;;;OAgBG;IACH,mBAAmB,CACjB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,OAAO,EACrB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,EACxB,kBAAkB,CAAC,EAAE,2BAA2B,GAC/C,gBAAgB;IA4JnB;;;;;OAKG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO;IAOxE;;;;;OAKG;IACH,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO;CAOtD"}
@@ -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
@@ -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
+ }