@securecode-ai/mcp 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/api/client.d.ts +4 -0
- package/dist/api/client.js +49 -0
- package/dist/api/client.js.map +1 -1
- package/dist/api/types.d.ts +40 -0
- package/dist/index.js +64 -7
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +16 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/poc/httpPocExecutor.d.ts +20 -0
- package/dist/poc/httpPocExecutor.js +247 -0
- package/dist/poc/httpPocExecutor.js.map +1 -0
- package/dist/poc/lightpandaExecutor.d.ts +41 -0
- package/dist/poc/lightpandaExecutor.js +263 -0
- package/dist/poc/lightpandaExecutor.js.map +1 -0
- package/dist/poc/pocExecutor.d.ts +46 -0
- package/dist/poc/pocExecutor.js +74 -0
- package/dist/poc/pocExecutor.js.map +1 -0
- package/dist/poc/pocRouter.d.ts +20 -0
- package/dist/poc/pocRouter.js +40 -0
- package/dist/poc/pocRouter.js.map +1 -0
- package/dist/poc/pocTypes.d.ts +54 -0
- package/dist/poc/pocTypes.js +16 -0
- package/dist/poc/pocTypes.js.map +1 -0
- package/dist/project-map/fixTester.d.ts +55 -0
- package/dist/project-map/fixTester.js +338 -0
- package/dist/project-map/fixTester.js.map +1 -0
- package/dist/project-map/guardEvaluator.d.ts +40 -0
- package/dist/project-map/guardEvaluator.js +216 -0
- package/dist/project-map/guardEvaluator.js.map +1 -0
- package/dist/project-map/guardPatterns.d.ts +43 -0
- package/dist/project-map/guardPatterns.js +173 -0
- package/dist/project-map/guardPatterns.js.map +1 -0
- package/dist/project-map/mapBuilder.js +44 -5
- package/dist/project-map/mapBuilder.js.map +1 -1
- package/dist/project-map/sanitizers.d.ts +34 -0
- package/dist/project-map/sanitizers.js +76 -0
- package/dist/project-map/sanitizers.js.map +1 -0
- package/dist/project-map/sinkFinder.d.ts +48 -0
- package/dist/project-map/sinkFinder.js +340 -0
- package/dist/project-map/sinkFinder.js.map +1 -0
- package/dist/project-map/sinkRegistry.d.ts +60 -0
- package/dist/project-map/sinkRegistry.js +246 -0
- package/dist/project-map/sinkRegistry.js.map +1 -0
- package/dist/project-map/taintSources.d.ts +30 -0
- package/dist/project-map/taintSources.js +77 -0
- package/dist/project-map/taintSources.js.map +1 -0
- package/dist/project-map/taintTracker.d.ts +42 -0
- package/dist/project-map/taintTracker.js +571 -0
- package/dist/project-map/taintTracker.js.map +1 -0
- package/dist/tools/map.js +13 -1
- package/dist/tools/map.js.map +1 -1
- package/dist/tools/scan.js +44 -0
- package/dist/tools/scan.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Phase B — declarative sink registry for the AST sink finder.
|
|
4
|
+
*
|
|
5
|
+
* Each entry describes a dangerous operation (a "sink") that the finder
|
|
6
|
+
* matches against the parsed AST. The registry is deliberately conservative
|
|
7
|
+
* on false negatives (high recall): a missed sink is a missed vulnerability,
|
|
8
|
+
* while a false sink is dismissed by the Juror at no structural cost.
|
|
9
|
+
*
|
|
10
|
+
* The canonical types mirror `api/src/services/taxonomy.ts` CANONICAL_TYPES
|
|
11
|
+
* so the API can consume findings without translation.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.SINK_REGISTRY = void 0;
|
|
15
|
+
/**
|
|
16
|
+
* The sink registry. Superset of the 11 regex rules in
|
|
17
|
+
* `api/src/services/sinkFloorService.ts` plus Python sinks.
|
|
18
|
+
*
|
|
19
|
+
* Ordering is by severity (Critical first) so the finder, which stops at the
|
|
20
|
+
* first match per call site, prefers the most severe reading.
|
|
21
|
+
*/
|
|
22
|
+
exports.SINK_REGISTRY = [
|
|
23
|
+
// ── Command injection (JS/TS/TSX) ──────────────────────────────────────
|
|
24
|
+
{
|
|
25
|
+
id: 'exec',
|
|
26
|
+
canonicalType: 'command_injection',
|
|
27
|
+
severity: 'Critical',
|
|
28
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
29
|
+
matchers: [
|
|
30
|
+
{ kind: 'call', method: 'exec' }, // bare: const { exec } = require('child_process'); exec(cmd)
|
|
31
|
+
{ kind: 'call', method: 'exec', receiver: 'child_process' },
|
|
32
|
+
],
|
|
33
|
+
description: 'child_process.exec / destructured exec — shell command execution',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'spawn',
|
|
37
|
+
canonicalType: 'command_injection',
|
|
38
|
+
severity: 'Critical',
|
|
39
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
40
|
+
matchers: [
|
|
41
|
+
{ kind: 'call', method: 'spawn' }, // bare: const { spawn } = require('child_process'); spawn(cmd)
|
|
42
|
+
{ kind: 'call', method: 'spawn', receiver: 'child_process' },
|
|
43
|
+
],
|
|
44
|
+
description: 'child_process.spawn — process spawning',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'execFile',
|
|
48
|
+
canonicalType: 'command_injection',
|
|
49
|
+
severity: 'Critical',
|
|
50
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
51
|
+
matchers: [
|
|
52
|
+
{ kind: 'call', method: 'execFile' },
|
|
53
|
+
{ kind: 'call', method: 'execFile', receiver: 'child_process' },
|
|
54
|
+
],
|
|
55
|
+
description: 'child_process.execFile — file execution',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'fork',
|
|
59
|
+
canonicalType: 'command_injection',
|
|
60
|
+
severity: 'Critical',
|
|
61
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
62
|
+
matchers: [
|
|
63
|
+
{ kind: 'call', method: 'fork' },
|
|
64
|
+
{ kind: 'call', method: 'fork', receiver: 'child_process' },
|
|
65
|
+
],
|
|
66
|
+
description: 'child_process.fork — process forking',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'eval',
|
|
70
|
+
canonicalType: 'command_injection',
|
|
71
|
+
severity: 'Critical',
|
|
72
|
+
languages: ['javascript', 'typescript', 'tsx', 'python'],
|
|
73
|
+
matchers: [{ kind: 'call', method: 'eval' }],
|
|
74
|
+
description: 'eval() — arbitrary code execution',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'Function',
|
|
78
|
+
canonicalType: 'command_injection',
|
|
79
|
+
severity: 'Critical',
|
|
80
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
81
|
+
matchers: [{ kind: 'call', method: 'Function' }],
|
|
82
|
+
description: 'Function() constructor — code execution from string',
|
|
83
|
+
},
|
|
84
|
+
// ── Command injection (Python) ─────────────────────────────────────────
|
|
85
|
+
{
|
|
86
|
+
id: 'os.system',
|
|
87
|
+
canonicalType: 'command_injection',
|
|
88
|
+
severity: 'Critical',
|
|
89
|
+
languages: ['python'],
|
|
90
|
+
matchers: [{ kind: 'call', method: 'system', receiver: 'os' }],
|
|
91
|
+
description: 'os.system() — shell command execution',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: 'subprocess',
|
|
95
|
+
canonicalType: 'command_injection',
|
|
96
|
+
severity: 'Critical',
|
|
97
|
+
languages: ['python'],
|
|
98
|
+
matchers: [
|
|
99
|
+
{ kind: 'call', method: 'call', receiver: 'subprocess' },
|
|
100
|
+
{ kind: 'call', method: 'Popen', receiver: 'subprocess' },
|
|
101
|
+
{ kind: 'call', method: 'run', receiver: 'subprocess' },
|
|
102
|
+
{ kind: 'call', method: 'check_output', receiver: 'subprocess' },
|
|
103
|
+
],
|
|
104
|
+
description: 'subprocess.* — process execution',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'py-exec',
|
|
108
|
+
canonicalType: 'command_injection',
|
|
109
|
+
severity: 'Critical',
|
|
110
|
+
languages: ['python'],
|
|
111
|
+
matchers: [{ kind: 'call', method: 'exec' }],
|
|
112
|
+
description: 'Python exec() — arbitrary code execution',
|
|
113
|
+
},
|
|
114
|
+
// ── SQL injection (JS/TS/TSX) ──────────────────────────────────────────
|
|
115
|
+
{
|
|
116
|
+
id: 'queryRaw',
|
|
117
|
+
canonicalType: 'sql_injection',
|
|
118
|
+
severity: 'Critical',
|
|
119
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
120
|
+
matchers: [{ kind: 'call', method: '$queryRaw', receiver: '*' }],
|
|
121
|
+
requireNonLiteralArg: true,
|
|
122
|
+
description: 'Prisma $queryRaw with interpolation — SQL injection',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: 'sql-concat',
|
|
126
|
+
canonicalType: 'sql_injection',
|
|
127
|
+
severity: 'Critical',
|
|
128
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
129
|
+
matchers: [{ kind: 'call', method: 'query', receiver: '*' }],
|
|
130
|
+
requireNonLiteralArg: true,
|
|
131
|
+
description: 'db.query with non-literal argument — potential SQL injection',
|
|
132
|
+
},
|
|
133
|
+
// ── SQL injection (Python) ─────────────────────────────────────────────
|
|
134
|
+
{
|
|
135
|
+
id: 'cursor-execute',
|
|
136
|
+
canonicalType: 'sql_injection',
|
|
137
|
+
severity: 'Critical',
|
|
138
|
+
languages: ['python'],
|
|
139
|
+
matchers: [{ kind: 'call', method: 'execute', receiver: '*' }],
|
|
140
|
+
requireNonLiteralArg: true,
|
|
141
|
+
description: 'cursor.execute with non-literal argument — potential SQL injection',
|
|
142
|
+
},
|
|
143
|
+
// ── XSS (JS/TS/TSX) ────────────────────────────────────────────────────
|
|
144
|
+
{
|
|
145
|
+
id: 'dangerouslySetInnerHTML',
|
|
146
|
+
canonicalType: 'xss',
|
|
147
|
+
severity: 'High',
|
|
148
|
+
languages: ['tsx'],
|
|
149
|
+
matchers: [{ kind: 'jsx-attribute', name: 'dangerouslySetInnerHTML' }],
|
|
150
|
+
description: 'React dangerouslySetInnerHTML — XSS via DOM injection',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: 'innerHTML',
|
|
154
|
+
canonicalType: 'xss',
|
|
155
|
+
severity: 'High',
|
|
156
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
157
|
+
matchers: [{ kind: 'member-assignment', property: 'innerHTML' }],
|
|
158
|
+
requireNonLiteralArg: true,
|
|
159
|
+
description: '.innerHTML assignment — XSS via DOM injection',
|
|
160
|
+
},
|
|
161
|
+
// ── Open redirect (JS/TS/TSX) ──────────────────────────────────────────
|
|
162
|
+
{
|
|
163
|
+
id: 'res.redirect',
|
|
164
|
+
canonicalType: 'open_redirect',
|
|
165
|
+
severity: 'Medium',
|
|
166
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
167
|
+
matchers: [{ kind: 'call', method: 'redirect', receiver: '*' }],
|
|
168
|
+
requireNonLiteralArg: true,
|
|
169
|
+
description: 'res.redirect with non-literal argument — open redirect',
|
|
170
|
+
},
|
|
171
|
+
// ── Path traversal (JS/TS/TSX) ──────────────────────────────────────────
|
|
172
|
+
{
|
|
173
|
+
id: 'fs-read-write',
|
|
174
|
+
canonicalType: 'path_traversal',
|
|
175
|
+
severity: 'High',
|
|
176
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
177
|
+
matchers: [
|
|
178
|
+
{ kind: 'call', method: 'readFile', receiver: 'fs' },
|
|
179
|
+
{ kind: 'call', method: 'readFileSync', receiver: 'fs' },
|
|
180
|
+
{ kind: 'call', method: 'writeFile', receiver: 'fs' },
|
|
181
|
+
{ kind: 'call', method: 'writeFileSync', receiver: 'fs' },
|
|
182
|
+
{ kind: 'call', method: 'createReadStream', receiver: 'fs' },
|
|
183
|
+
{ kind: 'call', method: 'createWriteStream', receiver: 'fs' },
|
|
184
|
+
],
|
|
185
|
+
requireNonLiteralArg: true,
|
|
186
|
+
description: 'fs.readFile/writeFile with non-literal path — path traversal',
|
|
187
|
+
},
|
|
188
|
+
// ── Path traversal (Python) ─────────────────────────────────────────────
|
|
189
|
+
{
|
|
190
|
+
id: 'py-open',
|
|
191
|
+
canonicalType: 'path_traversal',
|
|
192
|
+
severity: 'High',
|
|
193
|
+
languages: ['python'],
|
|
194
|
+
matchers: [{ kind: 'call', method: 'open' }],
|
|
195
|
+
requireNonLiteralArg: true,
|
|
196
|
+
description: 'open() with non-literal path — path traversal',
|
|
197
|
+
},
|
|
198
|
+
// ── Insecure crypto (JS/TS/TSX) ─────────────────────────────────────────
|
|
199
|
+
{
|
|
200
|
+
id: 'createCipher',
|
|
201
|
+
canonicalType: 'insecure_crypto',
|
|
202
|
+
severity: 'Medium',
|
|
203
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
204
|
+
matchers: [
|
|
205
|
+
{ kind: 'call', method: 'createCipher', receiver: 'crypto' },
|
|
206
|
+
{ kind: 'call', method: 'createDecipher', receiver: 'crypto' },
|
|
207
|
+
],
|
|
208
|
+
description: 'crypto.createCipher/createDecipher — deprecated, use createCipheriv',
|
|
209
|
+
},
|
|
210
|
+
// ── Prototype pollution (JS/TS/TSX) ────────────────────────────────────
|
|
211
|
+
{
|
|
212
|
+
id: 'proto-merge',
|
|
213
|
+
canonicalType: 'prototype_pollution',
|
|
214
|
+
severity: 'High',
|
|
215
|
+
languages: ['javascript', 'typescript', 'tsx'],
|
|
216
|
+
matchers: [
|
|
217
|
+
{ kind: 'call', method: 'merge', receiver: '*' },
|
|
218
|
+
{ kind: 'call', method: 'defaultsDeep', receiver: '*' },
|
|
219
|
+
{ kind: 'call', method: 'deepCopy', receiver: '*' },
|
|
220
|
+
{ kind: 'call', method: 'extend', receiver: '*' },
|
|
221
|
+
],
|
|
222
|
+
requireNonLiteralArg: true,
|
|
223
|
+
description: 'Object merge/extend with user input — prototype pollution',
|
|
224
|
+
},
|
|
225
|
+
// ── Insecure deserialization (Python) ───────────────────────────────────
|
|
226
|
+
{
|
|
227
|
+
id: 'pickle-loads',
|
|
228
|
+
canonicalType: 'insecure_deserialization',
|
|
229
|
+
severity: 'High',
|
|
230
|
+
languages: ['python'],
|
|
231
|
+
matchers: [
|
|
232
|
+
{ kind: 'call', method: 'loads', receiver: 'pickle' },
|
|
233
|
+
{ kind: 'call', method: 'load', receiver: 'pickle' },
|
|
234
|
+
],
|
|
235
|
+
description: 'pickle.loads/load — insecure deserialization',
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
id: 'yaml-load',
|
|
239
|
+
canonicalType: 'insecure_deserialization',
|
|
240
|
+
severity: 'High',
|
|
241
|
+
languages: ['python'],
|
|
242
|
+
matchers: [{ kind: 'call', method: 'load', receiver: 'yaml' }],
|
|
243
|
+
description: 'yaml.load without SafeLoader — insecure deserialization',
|
|
244
|
+
},
|
|
245
|
+
];
|
|
246
|
+
//# sourceMappingURL=sinkRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sinkRegistry.js","sourceRoot":"","sources":["../../src/project-map/sinkRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase C — taint source patterns.
|
|
3
|
+
*
|
|
4
|
+
* Defines what constitutes attacker-controlled input. A member expression
|
|
5
|
+
* (or call on a member expression) is a source if its text starts with one
|
|
6
|
+
* of the patterns below. The taint tracker uses this to seed the tainted
|
|
7
|
+
* variable set during its forward walk.
|
|
8
|
+
*/
|
|
9
|
+
import type { SinkLanguage } from './sinkRegistry';
|
|
10
|
+
export type TaintSourceType = 'body' | 'query' | 'path' | 'header' | 'cookie' | 'stdin' | 'argv' | 'env';
|
|
11
|
+
export interface TaintSourcePattern {
|
|
12
|
+
/** Text prefix that identifies this source: 'req.body', 'request.GET', etc. */
|
|
13
|
+
prefix: string;
|
|
14
|
+
languages: SinkLanguage[];
|
|
15
|
+
sourceType: TaintSourceType;
|
|
16
|
+
/** How likely this is attacker-controlled (0-1). Body/query/path = 1.0, env = 0.5. */
|
|
17
|
+
confidence: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Source patterns for JS/TS/TSX and Python.
|
|
21
|
+
*
|
|
22
|
+
* JS/TS: Express, Fastify, Koa, Next.js, Lambda event.
|
|
23
|
+
* Python: Flask, Django, FastAPI, sys.argv, os.environ.
|
|
24
|
+
*/
|
|
25
|
+
export declare const TAINT_SOURCES: TaintSourcePattern[];
|
|
26
|
+
/**
|
|
27
|
+
* Check if an expression's text matches a taint source pattern.
|
|
28
|
+
* Returns the matching pattern, or null if not a source.
|
|
29
|
+
*/
|
|
30
|
+
export declare function matchTaintSource(text: string, language: SinkLanguage): TaintSourcePattern | null;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Phase C — taint source patterns.
|
|
4
|
+
*
|
|
5
|
+
* Defines what constitutes attacker-controlled input. A member expression
|
|
6
|
+
* (or call on a member expression) is a source if its text starts with one
|
|
7
|
+
* of the patterns below. The taint tracker uses this to seed the tainted
|
|
8
|
+
* variable set during its forward walk.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.TAINT_SOURCES = void 0;
|
|
12
|
+
exports.matchTaintSource = matchTaintSource;
|
|
13
|
+
/**
|
|
14
|
+
* Source patterns for JS/TS/TSX and Python.
|
|
15
|
+
*
|
|
16
|
+
* JS/TS: Express, Fastify, Koa, Next.js, Lambda event.
|
|
17
|
+
* Python: Flask, Django, FastAPI, sys.argv, os.environ.
|
|
18
|
+
*/
|
|
19
|
+
exports.TAINT_SOURCES = [
|
|
20
|
+
// ── JS/TS — Express / generic ───────────────────────────────────────
|
|
21
|
+
{ prefix: 'req.body', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'body', confidence: 1.0 },
|
|
22
|
+
{ prefix: 'req.query', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'query', confidence: 1.0 },
|
|
23
|
+
{ prefix: 'req.params', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'path', confidence: 1.0 },
|
|
24
|
+
{ prefix: 'req.headers', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'header', confidence: 0.9 },
|
|
25
|
+
{ prefix: 'req.cookies', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'cookie', confidence: 0.9 },
|
|
26
|
+
{ prefix: 'req.files', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'body', confidence: 0.9 },
|
|
27
|
+
// ── JS/TS — generic `request` object ─────────────────────────────────
|
|
28
|
+
{ prefix: 'request.body', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'body', confidence: 1.0 },
|
|
29
|
+
{ prefix: 'request.query', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'query', confidence: 1.0 },
|
|
30
|
+
{ prefix: 'request.params', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'path', confidence: 1.0 },
|
|
31
|
+
{ prefix: 'request.headers', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'header', confidence: 0.9 },
|
|
32
|
+
{ prefix: 'request.cookies', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'cookie', confidence: 0.9 },
|
|
33
|
+
// ── JS/TS — Koa ctx ───────────────────────────────────────────────────
|
|
34
|
+
{ prefix: 'ctx.request.body', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'body', confidence: 1.0 },
|
|
35
|
+
{ prefix: 'ctx.request.query', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'query', confidence: 1.0 },
|
|
36
|
+
{ prefix: 'ctx.request.params', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'path', confidence: 1.0 },
|
|
37
|
+
{ prefix: 'ctx.body', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'body', confidence: 1.0 },
|
|
38
|
+
{ prefix: 'ctx.query', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'query', confidence: 1.0 },
|
|
39
|
+
{ prefix: 'ctx.params', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'path', confidence: 1.0 },
|
|
40
|
+
{ prefix: 'ctx.headers', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'header', confidence: 0.9 },
|
|
41
|
+
// ── JS/TS — Lambda event ──────────────────────────────────────────────
|
|
42
|
+
{ prefix: 'event.body', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'body', confidence: 1.0 },
|
|
43
|
+
{ prefix: 'event.queryStringParameters', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'query', confidence: 1.0 },
|
|
44
|
+
{ prefix: 'event.pathParameters', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'path', confidence: 1.0 },
|
|
45
|
+
{ prefix: 'event.headers', languages: ['javascript', 'typescript', 'tsx'], sourceType: 'header', confidence: 0.9 },
|
|
46
|
+
// ── Python — Flask / Django / FastAPI ────────────────────────────────
|
|
47
|
+
{ prefix: 'request.GET', languages: ['python'], sourceType: 'query', confidence: 1.0 },
|
|
48
|
+
{ prefix: 'request.POST', languages: ['python'], sourceType: 'body', confidence: 1.0 },
|
|
49
|
+
{ prefix: 'request.args', languages: ['python'], sourceType: 'query', confidence: 1.0 },
|
|
50
|
+
{ prefix: 'request.form', languages: ['python'], sourceType: 'body', confidence: 1.0 },
|
|
51
|
+
{ prefix: 'request.json', languages: ['python'], sourceType: 'body', confidence: 1.0 },
|
|
52
|
+
{ prefix: 'request.body', languages: ['python'], sourceType: 'body', confidence: 1.0 },
|
|
53
|
+
{ prefix: 'request.headers', languages: ['python'], sourceType: 'header', confidence: 0.9 },
|
|
54
|
+
{ prefix: 'request.cookies', languages: ['python'], sourceType: 'cookie', confidence: 0.9 },
|
|
55
|
+
{ prefix: 'request.values', languages: ['python'], sourceType: 'query', confidence: 1.0 },
|
|
56
|
+
{ prefix: 'request.data', languages: ['python'], sourceType: 'body', confidence: 1.0 },
|
|
57
|
+
// ── Python — system ───────────────────────────────────────────────────
|
|
58
|
+
{ prefix: 'sys.argv', languages: ['python'], sourceType: 'argv', confidence: 0.7 },
|
|
59
|
+
{ prefix: 'os.environ', languages: ['python'], sourceType: 'env', confidence: 0.5 },
|
|
60
|
+
{ prefix: 'os.getenv', languages: ['python'], sourceType: 'env', confidence: 0.5 },
|
|
61
|
+
];
|
|
62
|
+
/**
|
|
63
|
+
* Check if an expression's text matches a taint source pattern.
|
|
64
|
+
* Returns the matching pattern, or null if not a source.
|
|
65
|
+
*/
|
|
66
|
+
function matchTaintSource(text, language) {
|
|
67
|
+
for (const src of exports.TAINT_SOURCES) {
|
|
68
|
+
if (!src.languages.includes(language))
|
|
69
|
+
continue;
|
|
70
|
+
// Exact match or prefix match (req.body.q starts with req.body)
|
|
71
|
+
if (text === src.prefix || text.startsWith(src.prefix + '.') || text.startsWith(src.prefix + '[')) {
|
|
72
|
+
return src;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=taintSources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taintSources.js","sourceRoot":"","sources":["../../src/project-map/taintSources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase C — taint propagation tracker.
|
|
3
|
+
*
|
|
4
|
+
* Walks a parsed file forward, maintaining a per-scope set of tainted
|
|
5
|
+
* variables. When a source access is found (req.body, request.GET, etc.),
|
|
6
|
+
* the variable is marked tainted. Taint propagates through assignments,
|
|
7
|
+
* concatenations, and template interpolations. Sanitizer calls strip
|
|
8
|
+
* taint. When a sink (from the sink registry) is encountered, the
|
|
9
|
+
* arguments are checked for taint — if tainted, a TaintResult is recorded
|
|
10
|
+
* with the full propagation path from source to sink.
|
|
11
|
+
*
|
|
12
|
+
* Intra-function: source and sink in the same function (the common case).
|
|
13
|
+
* Inter-function: a simple first pass identifies functions that return
|
|
14
|
+
* tainted data; calls to those functions propagate taint to the result.
|
|
15
|
+
*/
|
|
16
|
+
import { SinkLanguage } from './sinkRegistry';
|
|
17
|
+
export interface PropagationStep {
|
|
18
|
+
line: number;
|
|
19
|
+
variable: string;
|
|
20
|
+
operation: 'source' | 'assign' | 'concat' | 'template' | 'call-pass' | 'sink-arg';
|
|
21
|
+
description: string;
|
|
22
|
+
}
|
|
23
|
+
export interface TaintResult {
|
|
24
|
+
source: string;
|
|
25
|
+
sourceLine: number;
|
|
26
|
+
sink: string;
|
|
27
|
+
sinkLine: number;
|
|
28
|
+
canonicalType: string;
|
|
29
|
+
propagationPath: PropagationStep[];
|
|
30
|
+
isTainted: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Track taint propagation through source code. Returns a TaintResult for
|
|
34
|
+
* every sink where tainted data reaches an argument.
|
|
35
|
+
*
|
|
36
|
+
* @param source the file's source text
|
|
37
|
+
* @param language the grammar to parse with
|
|
38
|
+
* @returns taint results, one per tainted sink argument. Empty when the
|
|
39
|
+
* grammar is missing, the file fails to parse, or no tainted data
|
|
40
|
+
* reaches any sink (best-effort: never throws).
|
|
41
|
+
*/
|
|
42
|
+
export declare function trackTaint(source: string, language: SinkLanguage): Promise<TaintResult[]>;
|