@bryan-thompson/inspector-assessment-client 1.23.5 → 1.23.7
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/dist/assets/{OAuthCallback-DeXwqSKV.js → OAuthCallback-cHMTHdzd.js} +1 -1
- package/dist/assets/{OAuthDebugCallback-DyxX1t_p.js → OAuthDebugCallback-BAhy5GT7.js} +1 -1
- package/dist/assets/{index-5ZFeiSLu.js → index-Cw3SDcg4.js} +4 -4
- package/dist/index.html +1 -1
- package/lib/lib/securityPatterns.d.ts +1 -1
- package/lib/lib/securityPatterns.d.ts.map +1 -1
- package/lib/lib/securityPatterns.js +4 -2
- package/lib/services/assessment/modules/SecurityAssessor.d.ts +9 -0
- package/lib/services/assessment/modules/SecurityAssessor.d.ts.map +1 -1
- package/lib/services/assessment/modules/SecurityAssessor.js +51 -0
- 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-
|
|
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-Cw3SDcg4.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-
|
|
1
|
+
import { r as reactExports, S as SESSION_KEYS, p as parseOAuthCallbackParams, j as jsxRuntimeExports, g as generateOAuthErrorDescription } from "./index-Cw3SDcg4.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.23.
|
|
16323
|
+
const version$1 = "1.23.6";
|
|
16324
16324
|
const packageJson = {
|
|
16325
16325
|
name,
|
|
16326
16326
|
version: version$1
|
|
@@ -45217,7 +45217,7 @@ const useTheme = () => {
|
|
|
45217
45217
|
[theme, setThemeWithSideEffect]
|
|
45218
45218
|
);
|
|
45219
45219
|
};
|
|
45220
|
-
const version = "1.23.
|
|
45220
|
+
const version = "1.23.6";
|
|
45221
45221
|
var [createTooltipContext] = createContextScope("Tooltip", [
|
|
45222
45222
|
createPopperScope
|
|
45223
45223
|
]);
|
|
@@ -48774,13 +48774,13 @@ const App = () => {
|
|
|
48774
48774
|
) });
|
|
48775
48775
|
if (window.location.pathname === "/oauth/callback") {
|
|
48776
48776
|
const OAuthCallback = React.lazy(
|
|
48777
|
-
() => __vitePreload(() => import("./OAuthCallback-
|
|
48777
|
+
() => __vitePreload(() => import("./OAuthCallback-cHMTHdzd.js"), true ? [] : void 0)
|
|
48778
48778
|
);
|
|
48779
48779
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthCallback, { onConnect: onOAuthConnect }) });
|
|
48780
48780
|
}
|
|
48781
48781
|
if (window.location.pathname === "/oauth/callback/debug") {
|
|
48782
48782
|
const OAuthDebugCallback = React.lazy(
|
|
48783
|
-
() => __vitePreload(() => import("./OAuthDebugCallback-
|
|
48783
|
+
() => __vitePreload(() => import("./OAuthDebugCallback-BAhy5GT7.js"), true ? [] : void 0)
|
|
48784
48784
|
);
|
|
48785
48785
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(OAuthDebugCallback, { onConnect: onOAuthDebugConnect }) });
|
|
48786
48786
|
}
|
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-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-Cw3SDcg4.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-Df9Sx1jt.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Backend API Security Patterns
|
|
3
|
-
* Tests MCP server API security with
|
|
3
|
+
* Tests MCP server API security with 23 focused patterns
|
|
4
4
|
*
|
|
5
5
|
* Architecture: Attack-Type with Specific Payloads
|
|
6
6
|
* - Critical Injection (6 patterns): Command, Calculator, SQL, Path Traversal, XXE, NoSQL
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"securityPatterns.d.ts","sourceRoot":"","sources":["../../src/lib/securityPatterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"securityPatterns.d.ts","sourceRoot":"","sources":["../../src/lib/securityPatterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,EAAE,aAAa,EAuxCnD,CAAC;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,GACb,eAAe,EAAE,CAQnB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,aAAa,EAAE,CAEtD;AAED;;GAEG;AACH,wBAAgB,oBAAoB;;;;;;;;EA8BnC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Backend API Security Patterns
|
|
3
|
-
* Tests MCP server API security with
|
|
3
|
+
* Tests MCP server API security with 23 focused patterns
|
|
4
4
|
*
|
|
5
5
|
* Architecture: Attack-Type with Specific Payloads
|
|
6
6
|
* - Critical Injection (6 patterns): Command, Calculator, SQL, Path Traversal, XXE, NoSQL
|
|
@@ -49,7 +49,9 @@ export const SECURITY_ATTACK_PATTERNS = [
|
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
payload: "ls -la",
|
|
52
|
-
|
|
52
|
+
// Issue #27: Tighten pattern to require ls -la specific context
|
|
53
|
+
// Avoids false positives from "X total in memory" tool status messages
|
|
54
|
+
evidence: /(total\s+\d+\s*$|^[d-][rwx-]{9}\s+\d+|drwxr|permissions\s+denied)/im,
|
|
53
55
|
riskLevel: "HIGH",
|
|
54
56
|
description: "Directory listing command",
|
|
55
57
|
payloadType: "injection",
|
|
@@ -86,6 +86,15 @@ export declare class SecurityAssessor extends BaseAssessor {
|
|
|
86
86
|
* - "schema validation error: must be a string"
|
|
87
87
|
*/
|
|
88
88
|
private isMCPValidationError;
|
|
89
|
+
/**
|
|
90
|
+
* Check if response is an HTTP error (Issue #26)
|
|
91
|
+
* HTTP 4xx/5xx error responses indicate tool rejection, not vulnerability.
|
|
92
|
+
*
|
|
93
|
+
* This prevents false positives like "404: Not Found" being flagged for
|
|
94
|
+
* Calculator Injection (the digit "4" in "404" was incorrectly matching
|
|
95
|
+
* as the computed result of "2+2").
|
|
96
|
+
*/
|
|
97
|
+
private isHttpErrorResponse;
|
|
89
98
|
/**
|
|
90
99
|
* Check if evidence pattern is ambiguous (can match both validation and execution)
|
|
91
100
|
* These patterns appear in BOTH:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/SecurityAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,kBAAkB,EAInB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAc9D,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,iBAAiB,CAAuC;IAC1D,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuFrE;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAkC7B;;;;OAIG;YACW,yBAAyB;IA2KvC;;;;OAIG;YACW,qBAAqB;IA4JnC;;OAEG;YACW,WAAW;IA4HzB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAgDzB;;;OAGG;IACH,OAAO,CAAC,8BAA8B;IAiDtC;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAgClC;;;OAGG;IACH,OAAO,CAAC,eAAe;
|
|
1
|
+
{"version":3,"file":"SecurityAssessor.d.ts","sourceRoot":"","sources":["../../../../src/services/assessment/modules/SecurityAssessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,kBAAkB,EAInB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAc9D,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,iBAAiB,CAAuC;IAC1D,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuFrE;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAkC7B;;;;OAIG;YACW,yBAAyB;IA2KvC;;;;OAIG;YACW,qBAAqB;IA4JnC;;OAEG;YACW,WAAW;IA4HzB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAgDzB;;;OAGG;IACH,OAAO,CAAC,8BAA8B;IAiDtC;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAgClC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAkJvB;;;;;;;OAOG;IACH,OAAO,CAAC,qBAAqB;IAiE7B;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAqC5B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IA4B3B;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAsB3B;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;IAkC5B;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IA8F5B;;OAEG;YACW,+BAA+B;IAiC7C;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAYjC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA0B/B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAkEnC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAuI3B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAsB5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,oBAAoB;IAwN5B;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IAwDhC;;;OAGG;IACH,OAAO,CAAC,8BAA8B;IAuBtC;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAW9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,oBAAoB;IAoH5B;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;;OAGG;IACH,OAAO,CAAC,eAAe;IASvB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAiB9B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAmB3B"}
|
|
@@ -601,6 +601,15 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
601
601
|
evidence: `MCP validation error${errorCode}: Tool properly rejected invalid input before processing`,
|
|
602
602
|
};
|
|
603
603
|
}
|
|
604
|
+
// ✅ STEP 1.1: Check for HTTP error responses (Issue #26)
|
|
605
|
+
// HTTP 4xx/5xx errors indicate tool rejection, not vulnerability
|
|
606
|
+
// This prevents false positives like "404: Not Found" being flagged for Calculator Injection
|
|
607
|
+
if (this.isHttpErrorResponse(responseText)) {
|
|
608
|
+
return {
|
|
609
|
+
isVulnerable: false,
|
|
610
|
+
evidence: "HTTP error response indicates tool rejection (not vulnerability)",
|
|
611
|
+
};
|
|
612
|
+
}
|
|
604
613
|
// ✅ STEP 1.5: Classify tool and check for safe categories (prevents false positives)
|
|
605
614
|
// Check tool category before generic pattern matching to avoid false positives
|
|
606
615
|
const classifier = new ToolClassifier();
|
|
@@ -802,6 +811,33 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
802
811
|
];
|
|
803
812
|
return validationPatterns.some((pattern) => pattern.test(responseText));
|
|
804
813
|
}
|
|
814
|
+
/**
|
|
815
|
+
* Check if response is an HTTP error (Issue #26)
|
|
816
|
+
* HTTP 4xx/5xx error responses indicate tool rejection, not vulnerability.
|
|
817
|
+
*
|
|
818
|
+
* This prevents false positives like "404: Not Found" being flagged for
|
|
819
|
+
* Calculator Injection (the digit "4" in "404" was incorrectly matching
|
|
820
|
+
* as the computed result of "2+2").
|
|
821
|
+
*/
|
|
822
|
+
isHttpErrorResponse(responseText) {
|
|
823
|
+
// Pattern 1: HTTP status code followed by error description
|
|
824
|
+
// e.g., "404 Not Found", "500 Internal Server Error", "503 Service Unavailable"
|
|
825
|
+
const httpErrorPattern = /\b(4\d{2}|5\d{2})\b.*?(not found|error|bad request|unauthorized|forbidden|internal server|unavailable|timeout|service)/i;
|
|
826
|
+
// Pattern 2: Response starts with HTTP status code
|
|
827
|
+
// e.g., "404: Not Found", "500: Error"
|
|
828
|
+
const simpleHttpPattern = /^(4\d{2}|5\d{2})[\s:]/;
|
|
829
|
+
// Pattern 3: Short "not found" messages (common API error response)
|
|
830
|
+
// e.g., "Not Found", "Resource not found"
|
|
831
|
+
const notFoundPattern = /not found/i;
|
|
832
|
+
const isShortNotFound = notFoundPattern.test(responseText) && responseText.length < 100;
|
|
833
|
+
// Pattern 4: HTTP status in JSON error structure
|
|
834
|
+
// e.g., {"status": 404, "error": "Not Found"}
|
|
835
|
+
const jsonStatusPattern = /"status":\s*(4\d{2}|5\d{2})/;
|
|
836
|
+
return (httpErrorPattern.test(responseText) ||
|
|
837
|
+
simpleHttpPattern.test(responseText) ||
|
|
838
|
+
isShortNotFound ||
|
|
839
|
+
jsonStatusPattern.test(responseText));
|
|
840
|
+
}
|
|
805
841
|
/**
|
|
806
842
|
* Check if evidence pattern is ambiguous (can match both validation and execution)
|
|
807
843
|
* These patterns appear in BOTH:
|
|
@@ -874,6 +910,17 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
874
910
|
* Added for Issue #14: False positives on safe input reflection
|
|
875
911
|
*/
|
|
876
912
|
isComputedMathResult(payload, responseText) {
|
|
913
|
+
// Issue #26: Skip HTTP error responses - they indicate tool rejection, not computation
|
|
914
|
+
// HTTP 4xx/5xx status codes (e.g., "404: Not Found") should not trigger false positives
|
|
915
|
+
// The digit "4" in "404" was incorrectly matching as computed result of "2+2"
|
|
916
|
+
const httpErrorPattern = /\b(4\d{2}|5\d{2})\b.*?(not found|error|bad request|unauthorized|forbidden|internal server|unavailable|timeout)/i;
|
|
917
|
+
const simpleHttpPattern = /^(4\d{2}|5\d{2})[\s:]/; // Starts with HTTP status code
|
|
918
|
+
const notFoundPattern = /not found/i;
|
|
919
|
+
if (httpErrorPattern.test(responseText) ||
|
|
920
|
+
simpleHttpPattern.test(responseText) ||
|
|
921
|
+
(notFoundPattern.test(responseText) && responseText.length < 100)) {
|
|
922
|
+
return false; // HTTP error response, not a computed result
|
|
923
|
+
}
|
|
877
924
|
// Check if payload looks like a simple math expression
|
|
878
925
|
// Matches: "2+2", "15*37+100", "10/2", "5-3", etc.
|
|
879
926
|
const simpleMathPattern = /^\s*(\d+)\s*([+\-*/])\s*(\d+)(?:\s*([+\-*/])\s*(\d+))?\s*$/;
|
|
@@ -1174,6 +1221,10 @@ export class SecurityAssessor extends BaseAssessor {
|
|
|
1174
1221
|
isReflectionResponse(responseText) {
|
|
1175
1222
|
// Status message patterns (NEW)
|
|
1176
1223
|
const statusPatterns = [
|
|
1224
|
+
// Issue #27: Tool statistics/metrics messages (not command execution)
|
|
1225
|
+
// Prevents false positives from "1000 total in memory" style responses
|
|
1226
|
+
/\d+\s+total\s+(in\s+)?(memory|storage|items|results)/i,
|
|
1227
|
+
/\d+\s+(results|items|records),?\s+\d+\s+total/i,
|
|
1177
1228
|
// "Action executed successfully: <anything>" (generic status message)
|
|
1178
1229
|
/action\s+executed\s+successfully:/i,
|
|
1179
1230
|
/command\s+executed\s+successfully:/i,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bryan-thompson/inspector-assessment-client",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.7",
|
|
4
4
|
"description": "Client-side application for the Enhanced MCP Inspector with assessment capabilities",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Bryan Thompson <bryan@triepod.ai>",
|