circle-ir 3.1.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/LICENSE +15 -0
- package/README.md +200 -0
- package/configs/sinks/code_injection.yaml +672 -0
- package/configs/sinks/command.yaml +917 -0
- package/configs/sinks/deserialization.yaml +105 -0
- package/configs/sinks/ldap.yaml +136 -0
- package/configs/sinks/nodejs.json +629 -0
- package/configs/sinks/path.yaml +715 -0
- package/configs/sinks/python.json +501 -0
- package/configs/sinks/rust.json +339 -0
- package/configs/sinks/sql.yaml +233 -0
- package/configs/sinks/ssrf.yaml +160 -0
- package/configs/sinks/xpath.yaml +121 -0
- package/configs/sinks/xss.yaml +727 -0
- package/configs/sources/db_sources.yaml +90 -0
- package/configs/sources/env_sources.yaml +94 -0
- package/configs/sources/express.json +197 -0
- package/configs/sources/file_sources.yaml +164 -0
- package/configs/sources/http_sources.yaml +379 -0
- package/configs/sources/io_sources.yaml +519 -0
- package/configs/sources/network_sources.yaml +99 -0
- package/configs/sources/python.json +230 -0
- package/configs/sources/rust.json +286 -0
- package/configs/sources/spring.yaml +70 -0
- package/dist/analysis/advisory-db.d.ts +86 -0
- package/dist/analysis/advisory-db.js +104 -0
- package/dist/analysis/advisory-db.js.map +1 -0
- package/dist/analysis/cargo-parser.d.ts +42 -0
- package/dist/analysis/cargo-parser.js +102 -0
- package/dist/analysis/cargo-parser.js.map +1 -0
- package/dist/analysis/config-loader.d.ts +37 -0
- package/dist/analysis/config-loader.js +1561 -0
- package/dist/analysis/config-loader.js.map +1 -0
- package/dist/analysis/constant-propagation/ast-utils.d.ts +25 -0
- package/dist/analysis/constant-propagation/ast-utils.js +34 -0
- package/dist/analysis/constant-propagation/ast-utils.js.map +1 -0
- package/dist/analysis/constant-propagation/evaluator.d.ts +32 -0
- package/dist/analysis/constant-propagation/evaluator.js +296 -0
- package/dist/analysis/constant-propagation/evaluator.js.map +1 -0
- package/dist/analysis/constant-propagation/index.d.ts +62 -0
- package/dist/analysis/constant-propagation/index.js +152 -0
- package/dist/analysis/constant-propagation/index.js.map +1 -0
- package/dist/analysis/constant-propagation/patterns.d.ts +8 -0
- package/dist/analysis/constant-propagation/patterns.js +126 -0
- package/dist/analysis/constant-propagation/patterns.js.map +1 -0
- package/dist/analysis/constant-propagation/propagator.d.ts +180 -0
- package/dist/analysis/constant-propagation/propagator.js +1985 -0
- package/dist/analysis/constant-propagation/propagator.js.map +1 -0
- package/dist/analysis/constant-propagation/types.d.ts +63 -0
- package/dist/analysis/constant-propagation/types.js +5 -0
- package/dist/analysis/constant-propagation/types.js.map +1 -0
- package/dist/analysis/constant-propagation.d.ts +9 -0
- package/dist/analysis/constant-propagation.js +18 -0
- package/dist/analysis/constant-propagation.js.map +1 -0
- package/dist/analysis/dependency-scanner.d.ts +79 -0
- package/dist/analysis/dependency-scanner.js +122 -0
- package/dist/analysis/dependency-scanner.js.map +1 -0
- package/dist/analysis/dfg-verifier.d.ts +116 -0
- package/dist/analysis/dfg-verifier.js +399 -0
- package/dist/analysis/dfg-verifier.js.map +1 -0
- package/dist/analysis/findings.d.ts +11 -0
- package/dist/analysis/findings.js +228 -0
- package/dist/analysis/findings.js.map +1 -0
- package/dist/analysis/index.d.ts +16 -0
- package/dist/analysis/index.js +18 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/interprocedural.d.ts +99 -0
- package/dist/analysis/interprocedural.js +526 -0
- package/dist/analysis/interprocedural.js.map +1 -0
- package/dist/analysis/path-finder.d.ts +133 -0
- package/dist/analysis/path-finder.js +354 -0
- package/dist/analysis/path-finder.js.map +1 -0
- package/dist/analysis/rules.d.ts +75 -0
- package/dist/analysis/rules.js +332 -0
- package/dist/analysis/rules.js.map +1 -0
- package/dist/analysis/semver.d.ts +27 -0
- package/dist/analysis/semver.js +127 -0
- package/dist/analysis/semver.js.map +1 -0
- package/dist/analysis/taint-matcher.d.ts +15 -0
- package/dist/analysis/taint-matcher.js +634 -0
- package/dist/analysis/taint-matcher.js.map +1 -0
- package/dist/analysis/taint-propagation.d.ts +67 -0
- package/dist/analysis/taint-propagation.js +298 -0
- package/dist/analysis/taint-propagation.js.map +1 -0
- package/dist/analysis/unresolved.d.ts +14 -0
- package/dist/analysis/unresolved.js +202 -0
- package/dist/analysis/unresolved.js.map +1 -0
- package/dist/analyzer.d.ts +43 -0
- package/dist/analyzer.js +1010 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/browser/circle-ir.js +16576 -0
- package/dist/browser.d.ts +38 -0
- package/dist/browser.js +38 -0
- package/dist/browser.js.map +1 -0
- package/dist/core/circle-ir-core.cjs +13626 -0
- package/dist/core/circle-ir-core.d.ts +59 -0
- package/dist/core/circle-ir-core.js +13591 -0
- package/dist/core/extractors/calls.d.ts +13 -0
- package/dist/core/extractors/calls.js +1429 -0
- package/dist/core/extractors/calls.js.map +1 -0
- package/dist/core/extractors/cfg.d.ts +9 -0
- package/dist/core/extractors/cfg.js +519 -0
- package/dist/core/extractors/cfg.js.map +1 -0
- package/dist/core/extractors/dfg.d.ts +12 -0
- package/dist/core/extractors/dfg.js +1081 -0
- package/dist/core/extractors/dfg.js.map +1 -0
- package/dist/core/extractors/exports.d.ts +14 -0
- package/dist/core/extractors/exports.js +80 -0
- package/dist/core/extractors/exports.js.map +1 -0
- package/dist/core/extractors/imports.d.ts +9 -0
- package/dist/core/extractors/imports.js +739 -0
- package/dist/core/extractors/imports.js.map +1 -0
- package/dist/core/extractors/index.d.ts +10 -0
- package/dist/core/extractors/index.js +11 -0
- package/dist/core/extractors/index.js.map +1 -0
- package/dist/core/extractors/meta.d.ts +10 -0
- package/dist/core/extractors/meta.js +109 -0
- package/dist/core/extractors/meta.js.map +1 -0
- package/dist/core/extractors/types.d.ts +10 -0
- package/dist/core/extractors/types.js +1479 -0
- package/dist/core/extractors/types.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/parser.d.ts +84 -0
- package/dist/core/parser.js +250 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core-lib.d.ts +59 -0
- package/dist/core-lib.js +62 -0
- package/dist/core-lib.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/languages/index.d.ts +11 -0
- package/dist/languages/index.js +14 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/plugins/base.d.ts +44 -0
- package/dist/languages/plugins/base.js +82 -0
- package/dist/languages/plugins/base.js.map +1 -0
- package/dist/languages/plugins/index.d.ts +14 -0
- package/dist/languages/plugins/index.js +25 -0
- package/dist/languages/plugins/index.js.map +1 -0
- package/dist/languages/plugins/java.d.ts +49 -0
- package/dist/languages/plugins/java.js +402 -0
- package/dist/languages/plugins/java.js.map +1 -0
- package/dist/languages/plugins/javascript.d.ts +48 -0
- package/dist/languages/plugins/javascript.js +445 -0
- package/dist/languages/plugins/javascript.js.map +1 -0
- package/dist/languages/plugins/python.d.ts +47 -0
- package/dist/languages/plugins/python.js +480 -0
- package/dist/languages/plugins/python.js.map +1 -0
- package/dist/languages/plugins/rust.d.ts +47 -0
- package/dist/languages/plugins/rust.js +405 -0
- package/dist/languages/plugins/rust.js.map +1 -0
- package/dist/languages/registry.d.ts +30 -0
- package/dist/languages/registry.js +80 -0
- package/dist/languages/registry.js.map +1 -0
- package/dist/languages/types.d.ts +184 -0
- package/dist/languages/types.js +8 -0
- package/dist/languages/types.js.map +1 -0
- package/dist/resolution/cross-file.d.ts +146 -0
- package/dist/resolution/cross-file.js +439 -0
- package/dist/resolution/cross-file.js.map +1 -0
- package/dist/resolution/index.d.ts +12 -0
- package/dist/resolution/index.js +10 -0
- package/dist/resolution/index.js.map +1 -0
- package/dist/resolution/symbol-table.d.ts +136 -0
- package/dist/resolution/symbol-table.js +336 -0
- package/dist/resolution/symbol-table.js.map +1 -0
- package/dist/resolution/type-hierarchy.d.ts +124 -0
- package/dist/resolution/type-hierarchy.js +515 -0
- package/dist/resolution/type-hierarchy.js.map +1 -0
- package/dist/types/config.d.ts +45 -0
- package/dist/types/config.js +5 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +392 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +85 -0
- package/dist/utils/logger.js +198 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/wasm/tree-sitter-java.wasm +0 -0
- package/dist/wasm/tree-sitter-javascript.wasm +0 -0
- package/dist/wasm/tree-sitter-python.wasm +0 -0
- package/dist/wasm/tree-sitter-rust.wasm +0 -0
- package/dist/wasm/web-tree-sitter.wasm +0 -0
- package/docs/SPEC.md +1021 -0
- package/examples/browser-example.html +610 -0
- package/examples/node-example.ts +215 -0
- package/package.json +107 -0
- package/wasm/tree-sitter-java.wasm +0 -0
- package/wasm/tree-sitter-javascript.wasm +0 -0
- package/wasm/tree-sitter-python.wasm +0 -0
- package/wasm/tree-sitter-rust.wasm +0 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taint Propagation Engine
|
|
3
|
+
*
|
|
4
|
+
* Tracks taint through variable assignments, method returns, and field accesses
|
|
5
|
+
* using the DFG (Data Flow Graph) to find precise source-to-sink paths.
|
|
6
|
+
*/
|
|
7
|
+
import type { DFG, CallInfo, TaintSource, TaintSink, TaintSanitizer } from '../types/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Represents a tainted variable at a specific point in the code.
|
|
10
|
+
*/
|
|
11
|
+
export interface TaintedVariable {
|
|
12
|
+
variable: string;
|
|
13
|
+
defId: number;
|
|
14
|
+
line: number;
|
|
15
|
+
sourceType: string;
|
|
16
|
+
sourceLine: number;
|
|
17
|
+
confidence: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Represents a taint flow from source to sink.
|
|
21
|
+
*/
|
|
22
|
+
export interface TaintFlow {
|
|
23
|
+
source: TaintSource;
|
|
24
|
+
sink: TaintSink;
|
|
25
|
+
path: TaintFlowStep[];
|
|
26
|
+
sanitized: boolean;
|
|
27
|
+
sanitizer?: TaintSanitizer;
|
|
28
|
+
confidence: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A step in the taint flow path.
|
|
32
|
+
*/
|
|
33
|
+
export interface TaintFlowStep {
|
|
34
|
+
variable: string;
|
|
35
|
+
line: number;
|
|
36
|
+
type: 'source' | 'assignment' | 'use' | 'return' | 'field' | 'sink';
|
|
37
|
+
description: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Result of taint propagation analysis.
|
|
41
|
+
*/
|
|
42
|
+
export interface TaintPropagationResult {
|
|
43
|
+
taintedVars: TaintedVariable[];
|
|
44
|
+
flows: TaintFlow[];
|
|
45
|
+
reachableSinks: Map<TaintSink, TaintSource[]>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Propagate taint through the dataflow graph.
|
|
49
|
+
*/
|
|
50
|
+
export declare function propagateTaint(dfg: DFG, calls: CallInfo[], sources: TaintSource[], sinks: TaintSink[], sanitizers: TaintSanitizer[]): TaintPropagationResult;
|
|
51
|
+
/**
|
|
52
|
+
* Analyze method returns to propagate taint through return values.
|
|
53
|
+
*/
|
|
54
|
+
export declare function analyzeMethodReturns(dfg: DFG, calls: CallInfo[], taintedVars: TaintedVariable[]): TaintedVariable[];
|
|
55
|
+
/**
|
|
56
|
+
* Calculate confidence score for a taint flow.
|
|
57
|
+
*/
|
|
58
|
+
export declare function calculateFlowConfidence(flow: TaintFlow): number;
|
|
59
|
+
/**
|
|
60
|
+
* Get summary statistics for taint propagation.
|
|
61
|
+
*/
|
|
62
|
+
export declare function getTaintStats(result: TaintPropagationResult): {
|
|
63
|
+
totalTaintedVars: number;
|
|
64
|
+
totalFlows: number;
|
|
65
|
+
flowsBySinkType: Map<string, number>;
|
|
66
|
+
avgConfidence: number;
|
|
67
|
+
};
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taint Propagation Engine
|
|
3
|
+
*
|
|
4
|
+
* Tracks taint through variable assignments, method returns, and field accesses
|
|
5
|
+
* using the DFG (Data Flow Graph) to find precise source-to-sink paths.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Propagate taint through the dataflow graph.
|
|
9
|
+
*/
|
|
10
|
+
export function propagateTaint(dfg, calls, sources, sinks, sanitizers) {
|
|
11
|
+
const taintedVars = [];
|
|
12
|
+
const flows = [];
|
|
13
|
+
const reachableSinks = new Map();
|
|
14
|
+
// Build lookup maps
|
|
15
|
+
const defById = new Map();
|
|
16
|
+
const defsByLine = new Map();
|
|
17
|
+
const usesByLine = new Map();
|
|
18
|
+
const callsByLine = new Map();
|
|
19
|
+
const sanitizersByLine = new Map();
|
|
20
|
+
for (const def of dfg.defs) {
|
|
21
|
+
defById.set(def.id, def);
|
|
22
|
+
const existing = defsByLine.get(def.line) ?? [];
|
|
23
|
+
existing.push(def);
|
|
24
|
+
defsByLine.set(def.line, existing);
|
|
25
|
+
}
|
|
26
|
+
for (const use of dfg.uses) {
|
|
27
|
+
const existing = usesByLine.get(use.line) ?? [];
|
|
28
|
+
existing.push(use);
|
|
29
|
+
usesByLine.set(use.line, existing);
|
|
30
|
+
}
|
|
31
|
+
for (const call of calls) {
|
|
32
|
+
const existing = callsByLine.get(call.location.line) ?? [];
|
|
33
|
+
existing.push(call);
|
|
34
|
+
callsByLine.set(call.location.line, existing);
|
|
35
|
+
}
|
|
36
|
+
for (const san of sanitizers) {
|
|
37
|
+
const existing = sanitizersByLine.get(san.line) ?? [];
|
|
38
|
+
existing.push(san);
|
|
39
|
+
sanitizersByLine.set(san.line, existing);
|
|
40
|
+
}
|
|
41
|
+
// Step 1: Identify initial tainted definitions (from sources)
|
|
42
|
+
const initialTaint = findInitialTaint(sources, dfg, callsByLine, defsByLine);
|
|
43
|
+
taintedVars.push(...initialTaint);
|
|
44
|
+
// Step 2: Propagate taint through def-use chains
|
|
45
|
+
const propagatedTaint = propagateThroughChains(initialTaint, dfg.chains ?? [], defById, sanitizersByLine);
|
|
46
|
+
taintedVars.push(...propagatedTaint);
|
|
47
|
+
// Combine all tainted definitions
|
|
48
|
+
const allTaintedDefIds = new Set();
|
|
49
|
+
const taintByDefId = new Map();
|
|
50
|
+
for (const tv of taintedVars) {
|
|
51
|
+
allTaintedDefIds.add(tv.defId);
|
|
52
|
+
taintByDefId.set(tv.defId, tv);
|
|
53
|
+
}
|
|
54
|
+
// Step 3: Check which sinks are reachable from tainted variables
|
|
55
|
+
for (const sink of sinks) {
|
|
56
|
+
const usesAtSink = usesByLine.get(sink.line) ?? [];
|
|
57
|
+
const callsAtSink = callsByLine.get(sink.line) ?? [];
|
|
58
|
+
// Check if any argument to the sink call is tainted
|
|
59
|
+
for (const call of callsAtSink) {
|
|
60
|
+
for (const arg of call.arguments) {
|
|
61
|
+
if (arg.variable) {
|
|
62
|
+
// Find if this variable use is tainted
|
|
63
|
+
for (const use of usesAtSink) {
|
|
64
|
+
if (use.variable === arg.variable && use.def_id !== null) {
|
|
65
|
+
if (allTaintedDefIds.has(use.def_id)) {
|
|
66
|
+
const taintInfo = taintByDefId.get(use.def_id);
|
|
67
|
+
if (taintInfo) {
|
|
68
|
+
// Check if sanitized
|
|
69
|
+
const isSanitized = checkSanitized(taintInfo.line, sink.line, sink.type, sanitizersByLine);
|
|
70
|
+
if (!isSanitized.sanitized) {
|
|
71
|
+
// Find the source
|
|
72
|
+
const source = sources.find(s => s.line === taintInfo.sourceLine);
|
|
73
|
+
if (source) {
|
|
74
|
+
// Record the flow
|
|
75
|
+
const flow = buildTaintFlow(source, sink, taintInfo, dfg, defById);
|
|
76
|
+
flows.push(flow);
|
|
77
|
+
// Record reachable sink
|
|
78
|
+
const existingSources = reachableSinks.get(sink) ?? [];
|
|
79
|
+
if (!existingSources.some(s => s.line === source.line)) {
|
|
80
|
+
existingSources.push(source);
|
|
81
|
+
}
|
|
82
|
+
reachableSinks.set(sink, existingSources);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { taintedVars, flows, reachableSinks };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Find initial tainted definitions from sources.
|
|
97
|
+
*/
|
|
98
|
+
function findInitialTaint(sources, dfg, callsByLine, defsByLine) {
|
|
99
|
+
const tainted = [];
|
|
100
|
+
for (const source of sources) {
|
|
101
|
+
// Find definitions on the same line as the source
|
|
102
|
+
const defsOnLine = defsByLine.get(source.line) ?? [];
|
|
103
|
+
for (const def of defsOnLine) {
|
|
104
|
+
tainted.push({
|
|
105
|
+
variable: def.variable,
|
|
106
|
+
defId: def.id,
|
|
107
|
+
line: def.line,
|
|
108
|
+
sourceType: source.type,
|
|
109
|
+
sourceLine: source.line,
|
|
110
|
+
confidence: source.confidence,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// Also check the next line (for cases like: String x = request.getParameter("foo"))
|
|
114
|
+
const defsNextLine = defsByLine.get(source.line + 1) ?? [];
|
|
115
|
+
for (const def of defsNextLine) {
|
|
116
|
+
// Only include if there's a call on the source line
|
|
117
|
+
const callsOnSourceLine = callsByLine.get(source.line) ?? [];
|
|
118
|
+
if (callsOnSourceLine.length > 0) {
|
|
119
|
+
tainted.push({
|
|
120
|
+
variable: def.variable,
|
|
121
|
+
defId: def.id,
|
|
122
|
+
line: def.line,
|
|
123
|
+
sourceType: source.type,
|
|
124
|
+
sourceLine: source.line,
|
|
125
|
+
confidence: source.confidence * 0.9, // Slightly lower confidence
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return tainted;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Propagate taint through def-use chains.
|
|
134
|
+
*/
|
|
135
|
+
function propagateThroughChains(initialTaint, chains, defById, sanitizersByLine) {
|
|
136
|
+
const propagated = [];
|
|
137
|
+
const taintedDefIds = new Set(initialTaint.map(t => t.defId));
|
|
138
|
+
const taintInfoByDefId = new Map();
|
|
139
|
+
for (const t of initialTaint) {
|
|
140
|
+
taintInfoByDefId.set(t.defId, t);
|
|
141
|
+
}
|
|
142
|
+
// Build adjacency list for chains
|
|
143
|
+
const chainsByFromDef = new Map();
|
|
144
|
+
for (const chain of chains) {
|
|
145
|
+
const existing = chainsByFromDef.get(chain.from_def) ?? [];
|
|
146
|
+
existing.push(chain);
|
|
147
|
+
chainsByFromDef.set(chain.from_def, existing);
|
|
148
|
+
}
|
|
149
|
+
// BFS to propagate taint
|
|
150
|
+
const queue = [...initialTaint.map(t => t.defId)];
|
|
151
|
+
const visited = new Set(queue);
|
|
152
|
+
while (queue.length > 0) {
|
|
153
|
+
const currentDefId = queue.shift();
|
|
154
|
+
const currentTaint = taintInfoByDefId.get(currentDefId);
|
|
155
|
+
if (!currentTaint)
|
|
156
|
+
continue;
|
|
157
|
+
const outgoingChains = chainsByFromDef.get(currentDefId) ?? [];
|
|
158
|
+
for (const chain of outgoingChains) {
|
|
159
|
+
if (visited.has(chain.to_def))
|
|
160
|
+
continue;
|
|
161
|
+
const targetDef = defById.get(chain.to_def);
|
|
162
|
+
if (!targetDef)
|
|
163
|
+
continue;
|
|
164
|
+
// Check if there's a sanitizer between source and this def
|
|
165
|
+
const sanitizeCheck = checkSanitized(currentTaint.sourceLine, targetDef.line, currentTaint.sourceType, sanitizersByLine);
|
|
166
|
+
if (!sanitizeCheck.sanitized) {
|
|
167
|
+
const newTaint = {
|
|
168
|
+
variable: targetDef.variable,
|
|
169
|
+
defId: targetDef.id,
|
|
170
|
+
line: targetDef.line,
|
|
171
|
+
sourceType: currentTaint.sourceType,
|
|
172
|
+
sourceLine: currentTaint.sourceLine,
|
|
173
|
+
confidence: currentTaint.confidence * 0.95, // Decay confidence slightly
|
|
174
|
+
};
|
|
175
|
+
propagated.push(newTaint);
|
|
176
|
+
taintedDefIds.add(targetDef.id);
|
|
177
|
+
taintInfoByDefId.set(targetDef.id, newTaint);
|
|
178
|
+
visited.add(targetDef.id);
|
|
179
|
+
queue.push(targetDef.id);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return propagated;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Check if a taint flow is sanitized between two points.
|
|
187
|
+
*/
|
|
188
|
+
function checkSanitized(_fromLine, _toLine, _sinkType, _sanitizersByLine) {
|
|
189
|
+
// NOTE: The previous line-based sanitizer check was too aggressive.
|
|
190
|
+
// It would mark a flow as sanitized if ANY sanitizer existed between
|
|
191
|
+
// source and sink lines, even if that sanitizer was applied to a
|
|
192
|
+
// different variable (e.g., clean = sanitize(name); println(name);)
|
|
193
|
+
//
|
|
194
|
+
// The correct approach is to rely on:
|
|
195
|
+
// 1. DFG-based tracking - the tainted variable must flow through a sanitizer
|
|
196
|
+
// 2. The analyzer's sanitizedVars from constant propagation - which correctly
|
|
197
|
+
// tracks which specific variables were sanitized
|
|
198
|
+
//
|
|
199
|
+
// For now, return false and let the higher-level filtering handle sanitization.
|
|
200
|
+
// This prevents false negatives where unsanitized variables are incorrectly
|
|
201
|
+
// marked as safe just because a sanitizer exists somewhere on adjacent lines.
|
|
202
|
+
return { sanitized: false };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Build a taint flow path from source to sink.
|
|
206
|
+
*/
|
|
207
|
+
function buildTaintFlow(source, sink, taintInfo, dfg, defById) {
|
|
208
|
+
const path = [];
|
|
209
|
+
// Start with source
|
|
210
|
+
path.push({
|
|
211
|
+
variable: taintInfo.variable,
|
|
212
|
+
line: source.line,
|
|
213
|
+
type: 'source',
|
|
214
|
+
description: `Tainted data enters via ${source.type}`,
|
|
215
|
+
});
|
|
216
|
+
// Add intermediate assignments if we can trace them
|
|
217
|
+
// For now, just add the tainted variable assignment
|
|
218
|
+
if (taintInfo.line !== source.line) {
|
|
219
|
+
path.push({
|
|
220
|
+
variable: taintInfo.variable,
|
|
221
|
+
line: taintInfo.line,
|
|
222
|
+
type: 'assignment',
|
|
223
|
+
description: `Tainted value assigned to ${taintInfo.variable}`,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
// End with sink
|
|
227
|
+
path.push({
|
|
228
|
+
variable: taintInfo.variable,
|
|
229
|
+
line: sink.line,
|
|
230
|
+
type: 'sink',
|
|
231
|
+
description: `Tainted value reaches ${sink.type} sink`,
|
|
232
|
+
});
|
|
233
|
+
return {
|
|
234
|
+
source,
|
|
235
|
+
sink,
|
|
236
|
+
path,
|
|
237
|
+
sanitized: false,
|
|
238
|
+
confidence: taintInfo.confidence * 0.9, // Factor in path length
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Analyze method returns to propagate taint through return values.
|
|
243
|
+
*/
|
|
244
|
+
export function analyzeMethodReturns(dfg, calls, taintedVars) {
|
|
245
|
+
const additionalTaint = [];
|
|
246
|
+
const taintedDefIds = new Set(taintedVars.map(t => t.defId));
|
|
247
|
+
// Find return statements that return tainted values
|
|
248
|
+
const returnDefs = dfg.defs.filter(d => d.kind === 'return');
|
|
249
|
+
// For each return def, check if the returned value is tainted
|
|
250
|
+
for (const returnDef of returnDefs) {
|
|
251
|
+
// Find uses on the same line that might be the returned value
|
|
252
|
+
const usesOnLine = dfg.uses.filter(u => u.line === returnDef.line);
|
|
253
|
+
for (const use of usesOnLine) {
|
|
254
|
+
if (use.def_id !== null && taintedDefIds.has(use.def_id)) {
|
|
255
|
+
// This return statement returns a tainted value
|
|
256
|
+
// Now find calls to this method and taint their results
|
|
257
|
+
// (This would require method-level analysis which we'll add later)
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return additionalTaint;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Calculate confidence score for a taint flow.
|
|
265
|
+
*/
|
|
266
|
+
export function calculateFlowConfidence(flow) {
|
|
267
|
+
let confidence = 1.0;
|
|
268
|
+
// Factor 1: Source confidence
|
|
269
|
+
confidence *= flow.source.confidence;
|
|
270
|
+
// Factor 2: Path length (longer paths = less confident)
|
|
271
|
+
const pathLength = flow.path.length;
|
|
272
|
+
confidence *= Math.pow(0.95, pathLength - 2); // -2 for source and sink
|
|
273
|
+
// Factor 3: Sanitization
|
|
274
|
+
if (flow.sanitized) {
|
|
275
|
+
confidence = 0;
|
|
276
|
+
}
|
|
277
|
+
return Math.max(0, Math.min(1, confidence));
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Get summary statistics for taint propagation.
|
|
281
|
+
*/
|
|
282
|
+
export function getTaintStats(result) {
|
|
283
|
+
const flowsBySinkType = new Map();
|
|
284
|
+
for (const flow of result.flows) {
|
|
285
|
+
const count = flowsBySinkType.get(flow.sink.type) ?? 0;
|
|
286
|
+
flowsBySinkType.set(flow.sink.type, count + 1);
|
|
287
|
+
}
|
|
288
|
+
const avgConfidence = result.flows.length > 0
|
|
289
|
+
? result.flows.reduce((sum, f) => sum + f.confidence, 0) / result.flows.length
|
|
290
|
+
: 0;
|
|
291
|
+
return {
|
|
292
|
+
totalTaintedVars: result.taintedVars.length,
|
|
293
|
+
totalFlows: result.flows.length,
|
|
294
|
+
flowsBySinkType,
|
|
295
|
+
avgConfidence,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
//# 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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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unresolved item detector
|
|
3
|
+
*
|
|
4
|
+
* Identifies code patterns that require LLM assistance to resolve:
|
|
5
|
+
* - Virtual dispatch (interface methods)
|
|
6
|
+
* - Taint propagation through collections
|
|
7
|
+
* - Reflection calls
|
|
8
|
+
* - Dynamic method invocations
|
|
9
|
+
*/
|
|
10
|
+
import type { CallInfo, TypeInfo, DFG, UnresolvedItem } from '../types/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Detect unresolved items that would benefit from LLM analysis.
|
|
13
|
+
*/
|
|
14
|
+
export declare function detectUnresolved(calls: CallInfo[], types: TypeInfo[], dfg: DFG): UnresolvedItem[];
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unresolved item detector
|
|
3
|
+
*
|
|
4
|
+
* Identifies code patterns that require LLM assistance to resolve:
|
|
5
|
+
* - Virtual dispatch (interface methods)
|
|
6
|
+
* - Taint propagation through collections
|
|
7
|
+
* - Reflection calls
|
|
8
|
+
* - Dynamic method invocations
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Detect unresolved items that would benefit from LLM analysis.
|
|
12
|
+
*/
|
|
13
|
+
export function detectUnresolved(calls, types, dfg) {
|
|
14
|
+
const unresolved = [];
|
|
15
|
+
// Detect virtual dispatch (unresolved interface/abstract method calls)
|
|
16
|
+
unresolved.push(...detectVirtualDispatch(calls));
|
|
17
|
+
// Detect reflection patterns
|
|
18
|
+
unresolved.push(...detectReflection(calls));
|
|
19
|
+
// Detect taint propagation uncertainty (collections, etc.)
|
|
20
|
+
unresolved.push(...detectTaintPropagationUncertainty(calls, dfg));
|
|
21
|
+
// Detect dynamic calls
|
|
22
|
+
unresolved.push(...detectDynamicCalls(calls));
|
|
23
|
+
return unresolved;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Detect virtual dispatch - interface method calls that can't be statically resolved.
|
|
27
|
+
*/
|
|
28
|
+
function detectVirtualDispatch(calls) {
|
|
29
|
+
const items = [];
|
|
30
|
+
for (const call of calls) {
|
|
31
|
+
if (call.resolution?.status === 'interface_method') {
|
|
32
|
+
items.push({
|
|
33
|
+
type: 'virtual_dispatch',
|
|
34
|
+
call_id: calls.indexOf(call),
|
|
35
|
+
reason: 'interface_method_unknown_impl',
|
|
36
|
+
context: {
|
|
37
|
+
code: formatCallCode(call),
|
|
38
|
+
line: call.location.line,
|
|
39
|
+
candidates: call.resolution.candidates,
|
|
40
|
+
},
|
|
41
|
+
llm_question: `Which implementation of ${call.method_name} is called when invoked on ${call.receiver}? Consider the context and common patterns.`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return items;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Detect reflection patterns that need runtime analysis.
|
|
49
|
+
*/
|
|
50
|
+
function detectReflection(calls) {
|
|
51
|
+
const items = [];
|
|
52
|
+
const reflectionMethods = new Set([
|
|
53
|
+
'forName', // Class.forName
|
|
54
|
+
'newInstance', // Class.newInstance
|
|
55
|
+
'invoke', // Method.invoke
|
|
56
|
+
'get', // Field.get
|
|
57
|
+
'set', // Field.set
|
|
58
|
+
'getMethod', // Class.getMethod
|
|
59
|
+
'getDeclaredMethod',
|
|
60
|
+
'getField',
|
|
61
|
+
'getDeclaredField',
|
|
62
|
+
'getConstructor',
|
|
63
|
+
]);
|
|
64
|
+
const reflectionReceivers = new Set([
|
|
65
|
+
'Class',
|
|
66
|
+
'Method',
|
|
67
|
+
'Field',
|
|
68
|
+
'Constructor',
|
|
69
|
+
]);
|
|
70
|
+
for (const call of calls) {
|
|
71
|
+
const isReflectionMethod = reflectionMethods.has(call.method_name);
|
|
72
|
+
const isReflectionReceiver = call.receiver && reflectionReceivers.has(call.receiver);
|
|
73
|
+
if (isReflectionMethod || isReflectionReceiver) {
|
|
74
|
+
items.push({
|
|
75
|
+
type: 'reflection',
|
|
76
|
+
call_id: calls.indexOf(call),
|
|
77
|
+
reason: 'reflection_call',
|
|
78
|
+
context: {
|
|
79
|
+
code: formatCallCode(call),
|
|
80
|
+
line: call.location.line,
|
|
81
|
+
},
|
|
82
|
+
llm_question: `What class/method is being accessed via reflection at ${formatCallCode(call)}? What are the security implications?`,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return items;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Detect taint propagation uncertainty through collections and complex data flows.
|
|
90
|
+
*/
|
|
91
|
+
function detectTaintPropagationUncertainty(calls, dfg) {
|
|
92
|
+
const items = [];
|
|
93
|
+
// Collection methods that might propagate or lose taint
|
|
94
|
+
const collectionMethods = new Map([
|
|
95
|
+
['add', 'collection_add'],
|
|
96
|
+
['put', 'map_put'],
|
|
97
|
+
['get', 'collection_get'],
|
|
98
|
+
['remove', 'collection_remove'],
|
|
99
|
+
['addAll', 'collection_addAll'],
|
|
100
|
+
['putAll', 'map_putAll'],
|
|
101
|
+
['toArray', 'collection_toArray'],
|
|
102
|
+
['stream', 'collection_stream'],
|
|
103
|
+
['iterator', 'collection_iterator'],
|
|
104
|
+
]);
|
|
105
|
+
// Receivers that are likely collections
|
|
106
|
+
const collectionPatterns = [
|
|
107
|
+
/list/i,
|
|
108
|
+
/set/i,
|
|
109
|
+
/map/i,
|
|
110
|
+
/collection/i,
|
|
111
|
+
/array/i,
|
|
112
|
+
/queue/i,
|
|
113
|
+
/stack/i,
|
|
114
|
+
/vector/i,
|
|
115
|
+
];
|
|
116
|
+
for (const call of calls) {
|
|
117
|
+
if (!collectionMethods.has(call.method_name))
|
|
118
|
+
continue;
|
|
119
|
+
// Check if receiver looks like a collection
|
|
120
|
+
const isCollection = call.receiver && collectionPatterns.some(p => p.test(call.receiver));
|
|
121
|
+
if (!isCollection && call.receiver)
|
|
122
|
+
continue;
|
|
123
|
+
const methodType = collectionMethods.get(call.method_name);
|
|
124
|
+
// For add/put, check if argument might be tainted
|
|
125
|
+
if (methodType === 'collection_add' || methodType === 'map_put') {
|
|
126
|
+
const hasVariableArg = call.arguments.some(arg => arg.variable !== null);
|
|
127
|
+
if (hasVariableArg) {
|
|
128
|
+
items.push({
|
|
129
|
+
type: 'taint_propagation',
|
|
130
|
+
call_id: calls.indexOf(call),
|
|
131
|
+
reason: 'collection_taint_in',
|
|
132
|
+
context: {
|
|
133
|
+
code: formatCallCode(call),
|
|
134
|
+
line: call.location.line,
|
|
135
|
+
},
|
|
136
|
+
llm_question: `Does taint propagate into ${call.receiver} when ${call.method_name} is called? Will subsequent retrievals from this collection be tainted?`,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// For get operations, question if result carries taint
|
|
141
|
+
if (methodType === 'collection_get' || methodType === 'collection_toArray') {
|
|
142
|
+
items.push({
|
|
143
|
+
type: 'taint_propagation',
|
|
144
|
+
call_id: calls.indexOf(call),
|
|
145
|
+
reason: 'collection_taint_out',
|
|
146
|
+
context: {
|
|
147
|
+
code: formatCallCode(call),
|
|
148
|
+
line: call.location.line,
|
|
149
|
+
},
|
|
150
|
+
llm_question: `Does the value retrieved from ${call.receiver}.${call.method_name}() carry taint from previously added elements?`,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return items;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Detect dynamic method calls that can't be statically analyzed.
|
|
158
|
+
*/
|
|
159
|
+
function detectDynamicCalls(calls) {
|
|
160
|
+
const items = [];
|
|
161
|
+
// Patterns that suggest dynamic dispatch
|
|
162
|
+
const dynamicPatterns = [
|
|
163
|
+
{ method: 'execute', reason: 'command_pattern' },
|
|
164
|
+
{ method: 'handle', reason: 'handler_pattern' },
|
|
165
|
+
{ method: 'process', reason: 'processor_pattern' },
|
|
166
|
+
{ method: 'dispatch', reason: 'dispatcher_pattern' },
|
|
167
|
+
{ method: 'run', reason: 'runnable_pattern' },
|
|
168
|
+
{ method: 'call', reason: 'callable_pattern' },
|
|
169
|
+
{ method: 'apply', reason: 'function_pattern' },
|
|
170
|
+
{ method: 'accept', reason: 'consumer_pattern' },
|
|
171
|
+
];
|
|
172
|
+
for (const call of calls) {
|
|
173
|
+
// Skip if already resolved
|
|
174
|
+
if (call.resolved)
|
|
175
|
+
continue;
|
|
176
|
+
const pattern = dynamicPatterns.find(p => p.method === call.method_name);
|
|
177
|
+
if (pattern) {
|
|
178
|
+
items.push({
|
|
179
|
+
type: 'dynamic_call',
|
|
180
|
+
call_id: calls.indexOf(call),
|
|
181
|
+
reason: pattern.reason,
|
|
182
|
+
context: {
|
|
183
|
+
code: formatCallCode(call),
|
|
184
|
+
line: call.location.line,
|
|
185
|
+
},
|
|
186
|
+
llm_question: `What concrete implementation handles this ${call.method_name}() call? Analyze the code context to determine the actual target.`,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return items;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Format a call for display in context.
|
|
194
|
+
*/
|
|
195
|
+
function formatCallCode(call) {
|
|
196
|
+
const args = call.arguments.map(a => a.expression).join(', ');
|
|
197
|
+
if (call.receiver) {
|
|
198
|
+
return `${call.receiver}.${call.method_name}(${args})`;
|
|
199
|
+
}
|
|
200
|
+
return `${call.method_name}(${args})`;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=unresolved.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unresolved.js","sourceRoot":"","sources":["../../src/analysis/unresolved.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circle-IR Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for analyzing source code and producing Circle-IR output.
|
|
5
|
+
* This is the core analyzer - for LLM-enhanced analysis, use circle-ir-ai.
|
|
6
|
+
*/
|
|
7
|
+
import type { CircleIR, AnalysisResponse } from './types/index.js';
|
|
8
|
+
import type { TaintConfig } from './types/config.js';
|
|
9
|
+
import { type SupportedLanguage } from './core/index.js';
|
|
10
|
+
export interface AnalyzerOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Path to tree-sitter.wasm for parser initialization.
|
|
13
|
+
*/
|
|
14
|
+
wasmPath?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Paths to language-specific WASM files.
|
|
17
|
+
*/
|
|
18
|
+
languagePaths?: Partial<Record<SupportedLanguage, string>>;
|
|
19
|
+
/**
|
|
20
|
+
* Custom taint configuration.
|
|
21
|
+
*/
|
|
22
|
+
taintConfig?: TaintConfig;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Initialize the analyzer. Must be called before analyze().
|
|
26
|
+
*/
|
|
27
|
+
export declare function initAnalyzer(options?: AnalyzerOptions): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Analyze source code and produce Circle-IR output.
|
|
30
|
+
*/
|
|
31
|
+
export declare function analyze(code: string, filePath: string, language: SupportedLanguage, options?: AnalyzerOptions): Promise<CircleIR>;
|
|
32
|
+
/**
|
|
33
|
+
* Analyze code and return a simplified API response format.
|
|
34
|
+
*/
|
|
35
|
+
export declare function analyzeForAPI(code: string, filePath: string, language: SupportedLanguage, options?: AnalyzerOptions): Promise<AnalysisResponse>;
|
|
36
|
+
/**
|
|
37
|
+
* Check if the analyzer is initialized.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isAnalyzerInitialized(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Reset the analyzer (mainly for testing).
|
|
42
|
+
*/
|
|
43
|
+
export declare function resetAnalyzer(): void;
|