@kernlang/review 3.1.6 → 3.1.8

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 (150) hide show
  1. package/dist/cache.d.ts +1 -1
  2. package/dist/cache.js +5 -3
  3. package/dist/cache.js.map +1 -1
  4. package/dist/call-graph.d.ts +63 -0
  5. package/dist/call-graph.js +380 -0
  6. package/dist/call-graph.js.map +1 -0
  7. package/dist/concept-rules/boundary-mutation.d.ts +1 -1
  8. package/dist/concept-rules/boundary-mutation.js.map +1 -1
  9. package/dist/concept-rules/ignored-error.d.ts +1 -1
  10. package/dist/concept-rules/ignored-error.js.map +1 -1
  11. package/dist/concept-rules/illegal-dependency.d.ts +1 -1
  12. package/dist/concept-rules/illegal-dependency.js.map +1 -1
  13. package/dist/concept-rules/index.js +1 -6
  14. package/dist/concept-rules/index.js.map +1 -1
  15. package/dist/concept-rules/unguarded-effect.d.ts +1 -1
  16. package/dist/concept-rules/unguarded-effect.js.map +1 -1
  17. package/dist/concept-rules/unrecovered-effect.d.ts +1 -1
  18. package/dist/concept-rules/unrecovered-effect.js +2 -1
  19. package/dist/concept-rules/unrecovered-effect.js.map +1 -1
  20. package/dist/confidence.js +12 -8
  21. package/dist/confidence.js.map +1 -1
  22. package/dist/differ.js +3 -7
  23. package/dist/differ.js.map +1 -1
  24. package/dist/external-tools.js +5 -6
  25. package/dist/external-tools.js.map +1 -1
  26. package/dist/file-context.d.ts +21 -0
  27. package/dist/file-context.js +234 -0
  28. package/dist/file-context.js.map +1 -0
  29. package/dist/file-role.js +14 -7
  30. package/dist/file-role.js.map +1 -1
  31. package/dist/graph.d.ts +1 -1
  32. package/dist/graph.js +24 -16
  33. package/dist/graph.js.map +1 -1
  34. package/dist/index.d.ts +44 -35
  35. package/dist/index.js +210 -121
  36. package/dist/index.js.map +1 -1
  37. package/dist/inferrer.d.ts +8 -2
  38. package/dist/inferrer.js +80 -47
  39. package/dist/inferrer.js.map +1 -1
  40. package/dist/kern-lint.d.ts +3 -4
  41. package/dist/kern-lint.js +7 -5
  42. package/dist/kern-lint.js.map +1 -1
  43. package/dist/llm-bridge.d.ts +23 -7
  44. package/dist/llm-bridge.js +267 -31
  45. package/dist/llm-bridge.js.map +1 -1
  46. package/dist/llm-review.d.ts +16 -2
  47. package/dist/llm-review.js +240 -35
  48. package/dist/llm-review.js.map +1 -1
  49. package/dist/mappers/ts-concepts.d.ts +1 -1
  50. package/dist/mappers/ts-concepts.js +303 -32
  51. package/dist/mappers/ts-concepts.js.map +1 -1
  52. package/dist/norm-miner.d.ts +31 -0
  53. package/dist/norm-miner.js +119 -0
  54. package/dist/norm-miner.js.map +1 -0
  55. package/dist/obligations.d.ts +63 -0
  56. package/dist/obligations.js +158 -0
  57. package/dist/obligations.js.map +1 -0
  58. package/dist/quality-rules.d.ts +3 -3
  59. package/dist/quality-rules.js +4 -2
  60. package/dist/quality-rules.js.map +1 -1
  61. package/dist/reporter.d.ts +7 -2
  62. package/dist/reporter.js +82 -51
  63. package/dist/reporter.js.map +1 -1
  64. package/dist/rule-eval.d.ts +1 -2
  65. package/dist/rule-eval.js +5 -9
  66. package/dist/rule-eval.js.map +1 -1
  67. package/dist/rule-loader.js +16 -14
  68. package/dist/rule-loader.js.map +1 -1
  69. package/dist/rules/base.js +153 -69
  70. package/dist/rules/base.js.map +1 -1
  71. package/dist/rules/cli.js +23 -19
  72. package/dist/rules/cli.js.map +1 -1
  73. package/dist/rules/confidence.d.ts +1 -1
  74. package/dist/rules/confidence.js +5 -5
  75. package/dist/rules/confidence.js.map +1 -1
  76. package/dist/rules/dead-code.d.ts +10 -0
  77. package/dist/rules/dead-code.js +75 -0
  78. package/dist/rules/dead-code.js.map +1 -0
  79. package/dist/rules/dead-logic.js +35 -31
  80. package/dist/rules/dead-logic.js.map +1 -1
  81. package/dist/rules/express.d.ts +2 -1
  82. package/dist/rules/express.js +380 -126
  83. package/dist/rules/express.js.map +1 -1
  84. package/dist/rules/fastapi.js +53 -19
  85. package/dist/rules/fastapi.js.map +1 -1
  86. package/dist/rules/ground-layer.js +3 -3
  87. package/dist/rules/ground-layer.js.map +1 -1
  88. package/dist/rules/index.js +574 -105
  89. package/dist/rules/index.js.map +1 -1
  90. package/dist/rules/ink.js +9 -8
  91. package/dist/rules/ink.js.map +1 -1
  92. package/dist/rules/kern-source.js +202 -63
  93. package/dist/rules/kern-source.js.map +1 -1
  94. package/dist/rules/nextjs.js +88 -33
  95. package/dist/rules/nextjs.js.map +1 -1
  96. package/dist/rules/null-safety.js +52 -26
  97. package/dist/rules/null-safety.js.map +1 -1
  98. package/dist/rules/nuxt.js +24 -29
  99. package/dist/rules/nuxt.js.map +1 -1
  100. package/dist/rules/react.js +355 -69
  101. package/dist/rules/react.js.map +1 -1
  102. package/dist/rules/security-v2.js +71 -57
  103. package/dist/rules/security-v2.js.map +1 -1
  104. package/dist/rules/security-v3.js.map +1 -1
  105. package/dist/rules/security-v4.js +54 -27
  106. package/dist/rules/security-v4.js.map +1 -1
  107. package/dist/rules/security.js +35 -5
  108. package/dist/rules/security.js.map +1 -1
  109. package/dist/rules/terminal.js +17 -5
  110. package/dist/rules/terminal.js.map +1 -1
  111. package/dist/rules/vue.js +162 -107
  112. package/dist/rules/vue.js.map +1 -1
  113. package/dist/semantic-diff.d.ts +52 -0
  114. package/dist/semantic-diff.js +342 -0
  115. package/dist/semantic-diff.js.map +1 -0
  116. package/dist/spec-checker.js +11 -10
  117. package/dist/spec-checker.js.map +1 -1
  118. package/dist/suppression/apply-suppression.d.ts +2 -3
  119. package/dist/suppression/apply-suppression.js +3 -3
  120. package/dist/suppression/apply-suppression.js.map +1 -1
  121. package/dist/suppression/index.d.ts +2 -2
  122. package/dist/suppression/index.js +1 -1
  123. package/dist/suppression/index.js.map +1 -1
  124. package/dist/suppression/parse-directives.d.ts +1 -1
  125. package/dist/suppression/parse-directives.js +9 -4
  126. package/dist/suppression/parse-directives.js.map +1 -1
  127. package/dist/taint-ast.d.ts +20 -0
  128. package/dist/taint-ast.js +427 -0
  129. package/dist/taint-ast.js.map +1 -0
  130. package/dist/taint-crossfile.d.ts +28 -0
  131. package/dist/taint-crossfile.js +174 -0
  132. package/dist/taint-crossfile.js.map +1 -0
  133. package/dist/taint-findings.d.ts +17 -0
  134. package/dist/taint-findings.js +131 -0
  135. package/dist/taint-findings.js.map +1 -0
  136. package/dist/taint-regex.d.ts +61 -0
  137. package/dist/taint-regex.js +379 -0
  138. package/dist/taint-regex.js.map +1 -0
  139. package/dist/taint-types.d.ts +128 -0
  140. package/dist/taint-types.js +174 -0
  141. package/dist/taint-types.js.map +1 -0
  142. package/dist/taint.d.ts +13 -107
  143. package/dist/taint.js +16 -1067
  144. package/dist/taint.js.map +1 -1
  145. package/dist/template-detector.d.ts +2 -2
  146. package/dist/template-detector.js +11 -16
  147. package/dist/template-detector.js.map +1 -1
  148. package/dist/types.d.ts +35 -0
  149. package/dist/types.js.map +1 -1
  150. package/package.json +2 -2
@@ -0,0 +1,379 @@
1
+ /**
2
+ * Taint Tracking — Regex-based fallback engine.
3
+ *
4
+ * Used when no ts-morph SourceFile is available.
5
+ * Works on handler body strings from KERN IR nodes.
6
+ */
7
+ import { HTTP_PARAM_NAMES, HTTP_PARAM_TYPES, isSanitizerSufficient, SANITIZER_PATTERNS, SINK_PATTERNS, } from './taint-types.js';
8
+ // ── Main Regex Analysis ─────────────────────────────────────────────────
9
+ /**
10
+ * Regex-based taint analysis — legacy fallback for when no SourceFile is available.
11
+ */
12
+ export function analyzeTaintRegex(inferred, filePath) {
13
+ const results = [];
14
+ for (const r of inferred) {
15
+ if (r.node.type !== 'fn')
16
+ continue;
17
+ const fnName = r.node.props?.name || 'anonymous';
18
+ const paramsStr = r.node.props?.params || '';
19
+ // Get handler body
20
+ const handler = r.node.children?.find((c) => c.type === 'handler');
21
+ const code = handler?.props?.code || '';
22
+ if (!code)
23
+ continue;
24
+ // Step 1: Classify params as tainted
25
+ const taintedParams = classifyParams(paramsStr);
26
+ if (taintedParams.length === 0)
27
+ continue;
28
+ // Step 2: Propagate taint through assignments
29
+ const taintedVars = propagateTaint(code, taintedParams);
30
+ // Step 3: Find sinks that use tainted variables
31
+ const sinks = findTaintedSinks(code, taintedVars);
32
+ if (sinks.length === 0)
33
+ continue;
34
+ // Step 4: Check for sanitizers
35
+ const paths = buildPaths(code, taintedVars, sinks);
36
+ if (paths.length > 0) {
37
+ results.push({
38
+ fnName,
39
+ filePath,
40
+ startLine: r.startLine,
41
+ paths,
42
+ });
43
+ }
44
+ }
45
+ return results;
46
+ }
47
+ // ── Param Classification ────────────────────────────────────────────────
48
+ /**
49
+ * Classify function parameters as tainted or safe.
50
+ */
51
+ export function classifyParams(paramsStr) {
52
+ const sources = [];
53
+ if (!paramsStr)
54
+ return sources;
55
+ const params = paramsStr.split(',').map((p) => {
56
+ const parts = p.trim().split(':');
57
+ return { name: parts[0]?.trim(), type: parts[1]?.trim() || '' };
58
+ });
59
+ for (const p of params) {
60
+ if (!p.name)
61
+ continue;
62
+ if (HTTP_PARAM_NAMES.test(p.name) || HTTP_PARAM_TYPES.test(p.type)) {
63
+ sources.push({ name: p.name, origin: `${p.name} (HTTP input)` });
64
+ }
65
+ }
66
+ return sources;
67
+ }
68
+ // ── Multi-Hop Taint Propagation ─────────────────────────────────────────
69
+ /**
70
+ * Multi-hop taint propagation using worklist algorithm.
71
+ * Propagates until fixed point or configurable depth limit.
72
+ *
73
+ * Handles all assignment patterns:
74
+ * - const b = a
75
+ * - const b = a.trim()
76
+ * - const {x} = obj
77
+ * - let b; b = a
78
+ *
79
+ * @param code - Handler code string
80
+ * @param initialTainted - Set of initially tainted variable names
81
+ * @param maxDepth - Maximum propagation depth (default: 3)
82
+ * @returns Set of all tainted variable names after fixed point or depth limit
83
+ */
84
+ export function propagateTaintMultiHop(code, initialTainted, maxDepth = 3) {
85
+ const tainted = new Set(initialTainted);
86
+ const worklist = [];
87
+ const visitedAssignments = new Set();
88
+ const assignmentDepths = new Map();
89
+ for (const v of initialTainted) {
90
+ worklist.push({ varName: v, depth: 0 });
91
+ }
92
+ const allAssignments = extractAllAssignments(code);
93
+ while (worklist.length > 0) {
94
+ const { varName: currentVar, depth } = worklist.shift();
95
+ if (depth >= maxDepth)
96
+ continue;
97
+ for (const assignment of allAssignments) {
98
+ const { lhs, rhs, assignId } = assignment;
99
+ if (visitedAssignments.has(`${assignId}:${depth}`))
100
+ continue;
101
+ const rhsDeps = extractDependencies(rhs);
102
+ if (rhsDeps.has(currentVar)) {
103
+ visitedAssignments.add(`${assignId}:${depth}`);
104
+ const existingDepth = assignmentDepths.get(lhs);
105
+ if (existingDepth !== undefined && existingDepth <= depth + 1) {
106
+ continue;
107
+ }
108
+ assignmentDepths.set(lhs, depth + 1);
109
+ if (!tainted.has(lhs)) {
110
+ tainted.add(lhs);
111
+ worklist.push({ varName: lhs, depth: depth + 1 });
112
+ }
113
+ if (isCircularAssignment(lhs, rhs, allAssignments)) {
114
+ continue;
115
+ }
116
+ for (const dep of rhsDeps) {
117
+ if (dep !== currentVar && tainted.has(dep)) {
118
+ const depDepth = assignmentDepths.get(dep) ?? 0;
119
+ if (depth + 1 > depDepth) {
120
+ if (!tainted.has(lhs)) {
121
+ tainted.add(lhs);
122
+ worklist.push({ varName: lhs, depth: depth + 1 });
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ return tainted;
131
+ }
132
+ export function extractAllAssignments(code) {
133
+ const assignments = [];
134
+ const lines = code.split('\n');
135
+ let assignCounter = 0;
136
+ for (const line of lines) {
137
+ const trimmed = line.trim();
138
+ if (!trimmed || trimmed.startsWith('//') || trimmed.startsWith('*'))
139
+ continue;
140
+ for (const assign of parseLineAssignments(trimmed, assignCounter)) {
141
+ assignments.push(assign);
142
+ assignCounter++;
143
+ }
144
+ }
145
+ return assignments;
146
+ }
147
+ export function parseLineAssignments(line, lineNum) {
148
+ const assignments = [];
149
+ const constLetVarRegex = /^(?:const|let|var)\s+/;
150
+ const declMatch = line.match(constLetVarRegex);
151
+ if (!declMatch) {
152
+ const reassignRegex = /^(\w+)\s*=\s*(.+)$/;
153
+ const reassign = line.match(reassignRegex);
154
+ if (reassign) {
155
+ assignments.push({
156
+ lhs: reassign[1],
157
+ rhs: reassign[2],
158
+ assignId: `${lineNum}:reassign`,
159
+ });
160
+ }
161
+ return assignments;
162
+ }
163
+ const rest = line.slice(declMatch[0].length);
164
+ const destructRegex = /^\{\s*([^}]+)\}\s*=\s*(.+)$/;
165
+ const destructMatch = rest.match(destructRegex);
166
+ if (destructMatch) {
167
+ const vars = destructMatch[1]
168
+ .split(',')
169
+ .map((v) => {
170
+ const name = v.trim().split(':')[0].split('=')[0].trim();
171
+ return name;
172
+ })
173
+ .filter((v) => v && !v.startsWith('...'));
174
+ const rhs = destructMatch[2];
175
+ for (let i = 0; i < vars.length; i++) {
176
+ assignments.push({
177
+ lhs: vars[i],
178
+ rhs: `${rhs}[${i}]`,
179
+ assignId: `${lineNum}:destructure:${i}`,
180
+ });
181
+ }
182
+ return assignments;
183
+ }
184
+ const simpleAssignRegex = /^(\w+)\s*=\s*(.+)$/;
185
+ const simpleMatch = rest.match(simpleAssignRegex);
186
+ if (simpleMatch) {
187
+ assignments.push({
188
+ lhs: simpleMatch[1],
189
+ rhs: simpleMatch[2],
190
+ assignId: `${lineNum}:simple`,
191
+ });
192
+ }
193
+ return assignments;
194
+ }
195
+ export function extractDependencies(rhs) {
196
+ const deps = new Set();
197
+ const RESERVED = new Set([
198
+ 'undefined',
199
+ 'null',
200
+ 'true',
201
+ 'false',
202
+ 'const',
203
+ 'let',
204
+ 'var',
205
+ 'new',
206
+ 'typeof',
207
+ 'instanceof',
208
+ 'return',
209
+ 'await',
210
+ 'async',
211
+ 'function',
212
+ 'if',
213
+ 'else',
214
+ 'for',
215
+ 'while',
216
+ 'switch',
217
+ 'case',
218
+ 'break',
219
+ 'continue',
220
+ 'throw',
221
+ 'try',
222
+ 'catch',
223
+ 'finally',
224
+ ]);
225
+ // Match all identifier chains: foo, foo.bar, foo.bar.baz, foo[0].bar
226
+ const chainRegex = /\b([a-zA-Z_$]\w*)(?:\.\w+|\[[^\]]*\])*/g;
227
+ let match;
228
+ while ((match = chainRegex.exec(rhs)) !== null) {
229
+ const base = match[1];
230
+ if (!RESERVED.has(base) && !/^\d/.test(base)) {
231
+ deps.add(base);
232
+ }
233
+ }
234
+ return deps;
235
+ }
236
+ export function isCircularAssignment(lhs, rhs, allAssignments) {
237
+ const rhsDeps = extractDependencies(rhs);
238
+ const visited = new Set();
239
+ const stack = [...rhsDeps];
240
+ while (stack.length > 0) {
241
+ const current = stack.pop();
242
+ if (current === lhs)
243
+ return true;
244
+ if (visited.has(current))
245
+ continue;
246
+ visited.add(current);
247
+ for (const assign of allAssignments) {
248
+ if (assign.lhs === current) {
249
+ const deps = extractDependencies(assign.rhs);
250
+ for (const dep of deps) {
251
+ if (!visited.has(dep)) {
252
+ stack.push(dep);
253
+ }
254
+ }
255
+ }
256
+ }
257
+ }
258
+ return false;
259
+ }
260
+ // ── Taint Propagation ───────────────────────────────────────────────────
261
+ /**
262
+ * Propagate taint through variable assignments in handler body.
263
+ * Tracks: const x = req.body.foo → x is tainted.
264
+ * Returns all tainted variable names with their origins.
265
+ */
266
+ export function propagateTaint(code, params) {
267
+ const tainted = new Map();
268
+ for (const p of params) {
269
+ tainted.set(p.name, p);
270
+ }
271
+ const initialTainted = new Set(tainted.keys());
272
+ const propagated = propagateTaintMultiHop(code, initialTainted);
273
+ for (const v of propagated) {
274
+ if (!tainted.has(v)) {
275
+ tainted.set(v, { name: v, origin: `derived` });
276
+ }
277
+ }
278
+ return Array.from(tainted.values());
279
+ }
280
+ // ── Sink Detection ──────────────────────────────────────────────────────
281
+ /**
282
+ * Find sink calls that use tainted variables.
283
+ */
284
+ export function findTaintedSinks(code, taintedVars) {
285
+ const sinks = [];
286
+ const taintedNames = new Set(taintedVars.map((v) => v.name));
287
+ for (const { pattern, name, category } of SINK_PATTERNS) {
288
+ // Scan ALL matches using a global copy (original patterns are non-global)
289
+ const globalPattern = new RegExp(pattern.source, 'g');
290
+ let match;
291
+ while ((match = globalPattern.exec(code)) !== null) {
292
+ // Extract the argument region after the match
293
+ const callStart = match.index + match[0].length;
294
+ const parenDepth = findClosingParen(code, callStart);
295
+ const argText = code.slice(callStart, parenDepth);
296
+ // Check if any tainted variable is used in the arguments
297
+ for (const tName of taintedNames) {
298
+ if (new RegExp(`\\b${tName}\\b`).test(argText)) {
299
+ sinks.push({ name, category, taintedArg: tName });
300
+ break;
301
+ }
302
+ }
303
+ // Also check for template literals with tainted vars in any sink category
304
+ const templateMatch = argText.match(/`[^`]*\$\{(\w+)\}[^`]*`/);
305
+ if (templateMatch && taintedNames.has(templateMatch[1])) {
306
+ sinks.push({ name: `${name} (template)`, category, taintedArg: templateMatch[1] });
307
+ }
308
+ }
309
+ }
310
+ // Check template literals used in exec/spawn-like contexts
311
+ const templateExecRegex = /`[^`]*\$\{(\w+)\}[^`]*`/g;
312
+ let tm;
313
+ while ((tm = templateExecRegex.exec(code)) !== null) {
314
+ if (taintedNames.has(tm[1])) {
315
+ // Check if this template is used as argument to a command-like function
316
+ const before = code.slice(Math.max(0, tm.index - 50), tm.index);
317
+ if (/exec\s*\(|spawn\s*\(|execSync\s*\(/.test(before)) {
318
+ }
319
+ }
320
+ }
321
+ return sinks;
322
+ }
323
+ // ── Path Building ───────────────────────────────────────────────────────
324
+ /**
325
+ * Build taint paths and check for sanitizers between source and sink.
326
+ */
327
+ export function buildPaths(code, taintedVars, sinks) {
328
+ const paths = [];
329
+ const foundSanitizers = detectSanitizers(code);
330
+ for (const sink of sinks) {
331
+ // Find the source that produced this tainted arg
332
+ const source = taintedVars.find((v) => v.name === sink.taintedArg);
333
+ if (!source)
334
+ continue;
335
+ // Check if any sanitizer was applied to this specific variable
336
+ const sanitizer = foundSanitizers.find((s) => new RegExp(`\\b${sink.taintedArg}\\b`).test(s.context) ||
337
+ new RegExp(`${s.name}\\s*\\([^)]*\\b${sink.taintedArg}\\b`).test(code));
338
+ // Check sanitizer sufficiency — is this the RIGHT sanitizer for this sink?
339
+ const hasSanitizer = sanitizer != null;
340
+ const sufficient = sanitizer != null ? isSanitizerSufficient(sanitizer.name, sink.category) : false;
341
+ paths.push({
342
+ source,
343
+ sink,
344
+ sanitized: hasSanitizer && sufficient,
345
+ sanitizer: sanitizer?.name,
346
+ insufficientSanitizer: hasSanitizer && !sufficient ? sanitizer.name : undefined,
347
+ });
348
+ }
349
+ return paths;
350
+ }
351
+ // ── Sanitizer Detection ─────────────────────────────────────────────────
352
+ export function detectSanitizers(code) {
353
+ const found = [];
354
+ for (const { pattern, name } of SANITIZER_PATTERNS) {
355
+ const globalPattern = new RegExp(pattern.source, 'g');
356
+ let match;
357
+ while ((match = globalPattern.exec(code)) !== null) {
358
+ const start = Math.max(0, match.index - 50);
359
+ const end = Math.min(code.length, match.index + match[0].length + 50);
360
+ found.push({ name, context: code.slice(start, end) });
361
+ }
362
+ }
363
+ return found;
364
+ }
365
+ // ── Utilities ───────────────────────────────────────────────────────────
366
+ export function findClosingParen(code, start) {
367
+ let depth = 1;
368
+ for (let i = start; i < code.length; i++) {
369
+ if (code[i] === '(')
370
+ depth++;
371
+ if (code[i] === ')') {
372
+ depth--;
373
+ if (depth === 0)
374
+ return i;
375
+ }
376
+ }
377
+ return Math.min(start + 500, code.length); // fallback
378
+ }
379
+ //# sourceMappingURL=taint-regex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taint-regex.js","sourceRoot":"","sources":["../src/taint-regex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Taint Tracking — shared types, classification tables, and sanitizer sufficiency.
3
+ */
4
+ export interface TaintSource {
5
+ name: string;
6
+ origin: string;
7
+ line?: number;
8
+ }
9
+ export interface TaintSink {
10
+ name: string;
11
+ category: 'command' | 'fs' | 'sql' | 'redirect' | 'eval' | 'template' | 'codegen';
12
+ taintedArg: string;
13
+ line?: number;
14
+ }
15
+ export interface TaintPath {
16
+ source: TaintSource;
17
+ sink: TaintSink;
18
+ sanitized: boolean;
19
+ sanitizer?: string;
20
+ insufficientSanitizer?: string;
21
+ }
22
+ export interface TaintResult {
23
+ fnName: string;
24
+ filePath: string;
25
+ startLine: number;
26
+ paths: TaintPath[];
27
+ }
28
+ export interface CrossFileTaintResult {
29
+ callerFile: string;
30
+ callerFn: string;
31
+ callerLine: number;
32
+ calleeFile: string;
33
+ calleeFn: string;
34
+ taintedArgs: string[];
35
+ sinkInCallee: TaintSink;
36
+ source: TaintSource;
37
+ }
38
+ /** Map of exported function names → file path + param info */
39
+ export interface ExportedFunction {
40
+ filePath: string;
41
+ fnName: string;
42
+ params: string;
43
+ hasSink: boolean;
44
+ sinks: TaintSink[];
45
+ }
46
+ /** A function in the file that contains sinks — tracks which params flow to those sinks */
47
+ export interface InternalSinkFunction {
48
+ name: string;
49
+ /** Parameter indices whose values reach a sink in the function body */
50
+ taintedParamIndices: Set<number>;
51
+ /** Sink categories reachable from each param index (multiple categories per param) */
52
+ sinkCategories: Map<number, Set<TaintSink['category']>>;
53
+ }
54
+ /** Param names/types that indicate HTTP handler context */
55
+ export declare const HTTP_PARAM_NAMES: RegExp;
56
+ export declare const HTTP_PARAM_TYPES: RegExp;
57
+ /** User input access patterns — what flows from HTTP params */
58
+ export declare const USER_INPUT_ACCESS: readonly [{
59
+ readonly pattern: RegExp;
60
+ readonly origin: "req.body";
61
+ }, {
62
+ readonly pattern: RegExp;
63
+ readonly origin: "req.query";
64
+ }, {
65
+ readonly pattern: RegExp;
66
+ readonly origin: "req.params";
67
+ }, {
68
+ readonly pattern: RegExp;
69
+ readonly origin: "req.headers";
70
+ }, {
71
+ readonly pattern: RegExp;
72
+ readonly origin: "request.body";
73
+ }, {
74
+ readonly pattern: RegExp;
75
+ readonly origin: "request.query";
76
+ }, {
77
+ readonly pattern: RegExp;
78
+ readonly origin: "request.params";
79
+ }, {
80
+ readonly pattern: RegExp;
81
+ readonly origin: "process.argv";
82
+ }, {
83
+ readonly pattern: RegExp;
84
+ readonly origin: "process.env";
85
+ }, {
86
+ readonly pattern: RegExp;
87
+ readonly origin: "db.query";
88
+ }, {
89
+ readonly pattern: RegExp;
90
+ readonly origin: "findOne";
91
+ }, {
92
+ readonly pattern: RegExp;
93
+ readonly origin: "findById";
94
+ }, {
95
+ readonly pattern: RegExp;
96
+ readonly origin: "getItem";
97
+ }, {
98
+ readonly pattern: RegExp;
99
+ readonly origin: "collection.find";
100
+ }, {
101
+ readonly pattern: RegExp;
102
+ readonly origin: "vectorStore.search";
103
+ }, {
104
+ readonly pattern: RegExp;
105
+ readonly origin: "similaritySearch";
106
+ }, {
107
+ readonly pattern: RegExp;
108
+ readonly origin: "index.query";
109
+ }];
110
+ export interface SinkPattern {
111
+ pattern: RegExp;
112
+ name: string;
113
+ category: TaintSink['category'];
114
+ }
115
+ export declare const SINK_PATTERNS: SinkPattern[];
116
+ export declare const SANITIZER_PATTERNS: {
117
+ pattern: RegExp;
118
+ name: string;
119
+ }[];
120
+ export type SinkCategory = TaintSink['category'];
121
+ /**
122
+ * Check if a sanitizer is actually sufficient for a given sink category.
123
+ * Returns true if the sanitizer protects against the sink, false if it's
124
+ * a mismatch (e.g., parseInt used to "sanitize" command injection).
125
+ */
126
+ export declare function isSanitizerSufficient(sanitizerName: string, sinkCategory: SinkCategory): boolean;
127
+ export declare const SINK_NAMES: Map<string, "command" | "fs" | "sql" | "redirect" | "eval" | "template" | "codegen">;
128
+ export declare const SANITIZER_PATTERN_NAMES: string[];