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,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-File Call Resolution
|
|
3
|
+
*
|
|
4
|
+
* Resolves method calls to their definitions across file boundaries,
|
|
5
|
+
* enabling cross-file taint tracking.
|
|
6
|
+
*/
|
|
7
|
+
import { SymbolTable } from './symbol-table.js';
|
|
8
|
+
import { TypeHierarchyResolver } from './type-hierarchy.js';
|
|
9
|
+
/**
|
|
10
|
+
* CrossFileResolver - Resolves calls and tracks taint across files
|
|
11
|
+
*/
|
|
12
|
+
export class CrossFileResolver {
|
|
13
|
+
symbolTable;
|
|
14
|
+
typeHierarchy;
|
|
15
|
+
// Cache: file -> IR
|
|
16
|
+
fileIRs = new Map();
|
|
17
|
+
// Cache: method FQN -> taint info
|
|
18
|
+
methodTaintInfo = new Map();
|
|
19
|
+
// Resolved calls cache
|
|
20
|
+
resolvedCalls = new Map();
|
|
21
|
+
constructor(symbolTable, typeHierarchy) {
|
|
22
|
+
this.symbolTable = symbolTable;
|
|
23
|
+
this.typeHierarchy = typeHierarchy;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Add a file's IR for analysis
|
|
27
|
+
*/
|
|
28
|
+
addFile(filePath, ir) {
|
|
29
|
+
this.fileIRs.set(filePath, ir);
|
|
30
|
+
this.symbolTable.addFromIR(ir, filePath);
|
|
31
|
+
this.typeHierarchy.addFromIR(ir, filePath);
|
|
32
|
+
// Analyze methods for taint propagation characteristics
|
|
33
|
+
this.analyzeMethodTaint(ir, filePath);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve a call to its target method(s)
|
|
37
|
+
*/
|
|
38
|
+
resolveCall(call, fromFile) {
|
|
39
|
+
const cacheKey = `${fromFile}:${call.location.line}:${call.method_name}`;
|
|
40
|
+
if (this.resolvedCalls.has(cacheKey)) {
|
|
41
|
+
return this.resolvedCalls.get(cacheKey);
|
|
42
|
+
}
|
|
43
|
+
let resolved;
|
|
44
|
+
// Try to resolve based on receiver type
|
|
45
|
+
if (call.receiver) {
|
|
46
|
+
resolved = this.resolveWithReceiver(call, fromFile);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Static call or same-class call
|
|
50
|
+
resolved = this.resolveStaticOrLocal(call, fromFile);
|
|
51
|
+
}
|
|
52
|
+
if (resolved) {
|
|
53
|
+
this.resolvedCalls.set(cacheKey, resolved);
|
|
54
|
+
}
|
|
55
|
+
return resolved;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve call with a receiver (instance method call)
|
|
59
|
+
*/
|
|
60
|
+
resolveWithReceiver(call, fromFile) {
|
|
61
|
+
const receiver = call.receiver;
|
|
62
|
+
// Try to determine receiver type
|
|
63
|
+
const receiverType = this.inferReceiverType(receiver, fromFile);
|
|
64
|
+
if (receiverType) {
|
|
65
|
+
// Look for method in the type
|
|
66
|
+
const methodSymbol = this.symbolTable.findMethod(receiverType, call.method_name);
|
|
67
|
+
if (methodSymbol) {
|
|
68
|
+
return {
|
|
69
|
+
call,
|
|
70
|
+
sourceFile: fromFile,
|
|
71
|
+
targetFile: methodSymbol.file,
|
|
72
|
+
targetMethod: methodSymbol.fqn,
|
|
73
|
+
targetClass: methodSymbol.parentType || receiverType,
|
|
74
|
+
resolution: 'exact',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Check for polymorphic dispatch (interface/superclass)
|
|
78
|
+
const candidates = this.findPolymorphicCandidates(receiverType, call.method_name);
|
|
79
|
+
if (candidates.length > 0) {
|
|
80
|
+
const primary = candidates[0];
|
|
81
|
+
return {
|
|
82
|
+
call,
|
|
83
|
+
sourceFile: fromFile,
|
|
84
|
+
targetFile: primary.file,
|
|
85
|
+
targetMethod: primary.fqn,
|
|
86
|
+
targetClass: primary.parentType || receiverType,
|
|
87
|
+
resolution: 'polymorphic',
|
|
88
|
+
candidates: candidates.map(c => c.fqn),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Fallback: search by method name
|
|
93
|
+
return this.resolveByMethodName(call, fromFile);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Resolve static or local method call
|
|
97
|
+
*/
|
|
98
|
+
resolveStaticOrLocal(call, fromFile) {
|
|
99
|
+
// First check current file's types
|
|
100
|
+
const ir = this.fileIRs.get(fromFile);
|
|
101
|
+
if (ir) {
|
|
102
|
+
for (const type of ir.types) {
|
|
103
|
+
const pkg = type.package || ir.meta.package || '';
|
|
104
|
+
const typeFqn = pkg ? `${pkg}.${type.name}` : type.name;
|
|
105
|
+
for (const method of type.methods) {
|
|
106
|
+
if (method.name === call.method_name) {
|
|
107
|
+
return {
|
|
108
|
+
call,
|
|
109
|
+
sourceFile: fromFile,
|
|
110
|
+
targetFile: fromFile,
|
|
111
|
+
targetMethod: `${typeFqn}.${method.name}`,
|
|
112
|
+
targetClass: typeFqn,
|
|
113
|
+
resolution: 'exact',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Check imports and resolve
|
|
120
|
+
return this.resolveByMethodName(call, fromFile);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resolve by searching all known methods
|
|
124
|
+
*/
|
|
125
|
+
resolveByMethodName(call, fromFile) {
|
|
126
|
+
// Get all possible FQNs for the method name
|
|
127
|
+
const possibleFqns = this.symbolTable.getPossibleFqns(call.method_name);
|
|
128
|
+
for (const fqn of possibleFqns) {
|
|
129
|
+
const symbol = this.symbolTable.getSymbol(fqn);
|
|
130
|
+
if (symbol && symbol.kind === 'method') {
|
|
131
|
+
return {
|
|
132
|
+
call,
|
|
133
|
+
sourceFile: fromFile,
|
|
134
|
+
targetFile: symbol.file,
|
|
135
|
+
targetMethod: symbol.fqn,
|
|
136
|
+
targetClass: symbol.parentType || '',
|
|
137
|
+
resolution: 'inferred',
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Infer the type of a receiver variable
|
|
145
|
+
*/
|
|
146
|
+
inferReceiverType(receiver, fromFile) {
|
|
147
|
+
// Check if receiver is a known type name directly
|
|
148
|
+
const directType = this.symbolTable.resolveTypeName(receiver, fromFile);
|
|
149
|
+
if (directType)
|
|
150
|
+
return directType;
|
|
151
|
+
// Check file's IR for variable declarations
|
|
152
|
+
const ir = this.fileIRs.get(fromFile);
|
|
153
|
+
if (ir) {
|
|
154
|
+
// Look in DFG defs for type hints
|
|
155
|
+
for (const def of ir.dfg.defs) {
|
|
156
|
+
if (def.variable === receiver) {
|
|
157
|
+
// Try to find type from calls at this line
|
|
158
|
+
const callsAtLine = ir.calls.filter(c => c.location.line === def.line);
|
|
159
|
+
for (const call of callsAtLine) {
|
|
160
|
+
// Constructor call?
|
|
161
|
+
if (call.method_name === receiver || call.method_name === '<init>') {
|
|
162
|
+
return this.symbolTable.resolveTypeName(receiver, fromFile);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Try common type abbreviations
|
|
169
|
+
const commonTypes = {
|
|
170
|
+
'stmt': 'java.sql.Statement',
|
|
171
|
+
'pstmt': 'java.sql.PreparedStatement',
|
|
172
|
+
'conn': 'java.sql.Connection',
|
|
173
|
+
'rs': 'java.sql.ResultSet',
|
|
174
|
+
'request': 'javax.servlet.http.HttpServletRequest',
|
|
175
|
+
'response': 'javax.servlet.http.HttpServletResponse',
|
|
176
|
+
'req': 'javax.servlet.http.HttpServletRequest',
|
|
177
|
+
'res': 'javax.servlet.http.HttpServletResponse',
|
|
178
|
+
'session': 'javax.servlet.http.HttpSession',
|
|
179
|
+
'runtime': 'java.lang.Runtime',
|
|
180
|
+
'out': 'java.io.PrintWriter',
|
|
181
|
+
};
|
|
182
|
+
const lowerReceiver = receiver.toLowerCase();
|
|
183
|
+
for (const [abbrev, type] of Object.entries(commonTypes)) {
|
|
184
|
+
if (lowerReceiver.includes(abbrev)) {
|
|
185
|
+
return type;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Find polymorphic candidates (implementations/subclasses)
|
|
192
|
+
*/
|
|
193
|
+
findPolymorphicCandidates(typeName, methodName) {
|
|
194
|
+
const candidates = [];
|
|
195
|
+
// Get all implementations if it's an interface
|
|
196
|
+
const implementations = this.typeHierarchy.getAllImplementations(typeName);
|
|
197
|
+
for (const impl of implementations) {
|
|
198
|
+
const method = this.symbolTable.findMethod(impl, methodName);
|
|
199
|
+
if (method) {
|
|
200
|
+
candidates.push(method);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Get all subtypes if it's a class
|
|
204
|
+
const subtypes = this.typeHierarchy.getAllSubtypes(typeName);
|
|
205
|
+
for (const subtype of subtypes) {
|
|
206
|
+
const method = this.symbolTable.findMethod(subtype, methodName);
|
|
207
|
+
if (method) {
|
|
208
|
+
candidates.push(method);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return candidates;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Analyze methods for taint propagation characteristics
|
|
215
|
+
*/
|
|
216
|
+
analyzeMethodTaint(ir, filePath) {
|
|
217
|
+
const pkg = ir.meta.package || '';
|
|
218
|
+
for (const type of ir.types) {
|
|
219
|
+
const typeFqn = pkg ? `${pkg}.${type.name}` : type.name;
|
|
220
|
+
for (const method of type.methods) {
|
|
221
|
+
const methodFqn = `${typeFqn}.${method.name}`;
|
|
222
|
+
// Check if method is a taint source
|
|
223
|
+
const isSource = this.isMethodTaintSource(method, ir.taint.sources);
|
|
224
|
+
// Check if method propagates taint from parameters
|
|
225
|
+
const taintedParams = this.findTaintedParams(method, ir);
|
|
226
|
+
// Check if method sanitizes
|
|
227
|
+
const sanitizes = method.annotations.includes('sanitizer') ||
|
|
228
|
+
this.isSanitizerMethod(method.name);
|
|
229
|
+
const taintInfo = {
|
|
230
|
+
methodFqn,
|
|
231
|
+
file: filePath,
|
|
232
|
+
taintedParams,
|
|
233
|
+
returnsSource: isSource,
|
|
234
|
+
sourceType: isSource ? this.getSourceType(method, ir.taint.sources) : undefined,
|
|
235
|
+
sanitizes,
|
|
236
|
+
sanitizedTypes: sanitizes ? this.getSanitizedTypes(method.name) : undefined,
|
|
237
|
+
};
|
|
238
|
+
this.methodTaintInfo.set(methodFqn, taintInfo);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Check if method is a taint source
|
|
244
|
+
*/
|
|
245
|
+
isMethodTaintSource(method, sources) {
|
|
246
|
+
// Check annotation-based sources
|
|
247
|
+
const sourceAnnotations = ['RequestParam', 'RequestBody', 'PathVariable', 'QueryParam'];
|
|
248
|
+
for (const param of method.parameters) {
|
|
249
|
+
if (param.annotations.some(a => sourceAnnotations.includes(a))) {
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Check if any source is within this method
|
|
254
|
+
for (const source of sources) {
|
|
255
|
+
if (source.line >= method.start_line && source.line <= method.end_line) {
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Get source type for a method
|
|
263
|
+
*/
|
|
264
|
+
getSourceType(method, sources) {
|
|
265
|
+
for (const source of sources) {
|
|
266
|
+
if (source.line >= method.start_line && source.line <= method.end_line) {
|
|
267
|
+
return source.type;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Find which parameters propagate taint to return value
|
|
274
|
+
*/
|
|
275
|
+
findTaintedParams(method, ir) {
|
|
276
|
+
const taintedParams = [];
|
|
277
|
+
// Simple heuristic: if parameter is used in return statement, it propagates taint
|
|
278
|
+
// More sophisticated analysis would track actual data flow
|
|
279
|
+
for (let i = 0; i < method.parameters.length; i++) {
|
|
280
|
+
const param = method.parameters[i];
|
|
281
|
+
// Check if param has taint-related annotation
|
|
282
|
+
if (param.annotations.some(a => ['RequestParam', 'RequestBody', 'PathVariable'].includes(a))) {
|
|
283
|
+
taintedParams.push(i);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return taintedParams;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Check if method name suggests sanitization
|
|
290
|
+
*/
|
|
291
|
+
isSanitizerMethod(methodName) {
|
|
292
|
+
const sanitizerPatterns = [
|
|
293
|
+
'escape', 'encode', 'sanitize', 'validate', 'filter',
|
|
294
|
+
'htmlEncode', 'urlEncode', 'prepareStatement',
|
|
295
|
+
];
|
|
296
|
+
const lowerName = methodName.toLowerCase();
|
|
297
|
+
return sanitizerPatterns.some(p => lowerName.includes(p.toLowerCase()));
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Get types sanitized by a method
|
|
301
|
+
*/
|
|
302
|
+
getSanitizedTypes(methodName) {
|
|
303
|
+
const lowerName = methodName.toLowerCase();
|
|
304
|
+
const types = [];
|
|
305
|
+
if (lowerName.includes('html') || lowerName.includes('xss')) {
|
|
306
|
+
types.push('xss');
|
|
307
|
+
}
|
|
308
|
+
if (lowerName.includes('sql') || lowerName.includes('prepare')) {
|
|
309
|
+
types.push('sql_injection');
|
|
310
|
+
}
|
|
311
|
+
if (lowerName.includes('url')) {
|
|
312
|
+
types.push('ssrf', 'path_traversal');
|
|
313
|
+
}
|
|
314
|
+
if (lowerName.includes('command') || lowerName.includes('shell')) {
|
|
315
|
+
types.push('command_injection');
|
|
316
|
+
}
|
|
317
|
+
return types.length > 0 ? types : ['unknown'];
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Find all callers of a method across the project
|
|
321
|
+
*/
|
|
322
|
+
findCallers(methodFqn) {
|
|
323
|
+
const callers = [];
|
|
324
|
+
for (const [filePath, ir] of this.fileIRs) {
|
|
325
|
+
for (const call of ir.calls) {
|
|
326
|
+
const resolved = this.resolveCall(call, filePath);
|
|
327
|
+
if (resolved && resolved.targetMethod === methodFqn) {
|
|
328
|
+
callers.push(resolved);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return callers;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Find cross-file taint flows
|
|
336
|
+
*/
|
|
337
|
+
findCrossFileTaintFlows() {
|
|
338
|
+
const flows = [];
|
|
339
|
+
for (const [filePath, ir] of this.fileIRs) {
|
|
340
|
+
// Check each source in the file
|
|
341
|
+
for (const source of ir.taint.sources) {
|
|
342
|
+
// Find calls at or after the source line
|
|
343
|
+
for (const call of ir.calls) {
|
|
344
|
+
if (call.location.line < source.line)
|
|
345
|
+
continue;
|
|
346
|
+
const resolved = this.resolveCall(call, filePath);
|
|
347
|
+
if (resolved && resolved.targetFile !== filePath) {
|
|
348
|
+
// This is a cross-file call
|
|
349
|
+
// Check if any argument might be tainted
|
|
350
|
+
const taintedArgs = [];
|
|
351
|
+
for (let i = 0; i < call.arguments.length; i++) {
|
|
352
|
+
// Simple heuristic: if variable was defined at or after source, might be tainted
|
|
353
|
+
taintedArgs.push(i);
|
|
354
|
+
}
|
|
355
|
+
if (taintedArgs.length > 0) {
|
|
356
|
+
flows.push({
|
|
357
|
+
sourceFile: filePath,
|
|
358
|
+
sourceLine: source.line,
|
|
359
|
+
sourceType: source.type,
|
|
360
|
+
targetFile: resolved.targetFile,
|
|
361
|
+
targetLine: call.location.line,
|
|
362
|
+
targetMethod: resolved.targetMethod,
|
|
363
|
+
flowType: 'call_arg',
|
|
364
|
+
taintedArgPositions: taintedArgs,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return flows;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Get taint info for a method
|
|
375
|
+
*/
|
|
376
|
+
getMethodTaintInfo(methodFqn) {
|
|
377
|
+
return this.methodTaintInfo.get(methodFqn);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Get all resolved calls from a file
|
|
381
|
+
*/
|
|
382
|
+
getResolvedCallsFromFile(filePath) {
|
|
383
|
+
const ir = this.fileIRs.get(filePath);
|
|
384
|
+
if (!ir)
|
|
385
|
+
return [];
|
|
386
|
+
const resolved = [];
|
|
387
|
+
for (const call of ir.calls) {
|
|
388
|
+
const r = this.resolveCall(call, filePath);
|
|
389
|
+
if (r) {
|
|
390
|
+
resolved.push(r);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return resolved;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get statistics
|
|
397
|
+
*/
|
|
398
|
+
getStats() {
|
|
399
|
+
let totalCalls = 0;
|
|
400
|
+
let crossFileCalls = 0;
|
|
401
|
+
for (const [filePath, ir] of this.fileIRs) {
|
|
402
|
+
totalCalls += ir.calls.length;
|
|
403
|
+
for (const call of ir.calls) {
|
|
404
|
+
const resolved = this.resolveCall(call, filePath);
|
|
405
|
+
if (resolved && resolved.targetFile !== filePath) {
|
|
406
|
+
crossFileCalls++;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
totalFiles: this.fileIRs.size,
|
|
412
|
+
totalCalls,
|
|
413
|
+
resolvedCalls: this.resolvedCalls.size,
|
|
414
|
+
crossFileCalls,
|
|
415
|
+
methodsWithTaintInfo: this.methodTaintInfo.size,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Clear all caches
|
|
420
|
+
*/
|
|
421
|
+
clear() {
|
|
422
|
+
this.fileIRs.clear();
|
|
423
|
+
this.methodTaintInfo.clear();
|
|
424
|
+
this.resolvedCalls.clear();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Build a cross-file resolver from multiple IR results
|
|
429
|
+
*/
|
|
430
|
+
export function buildCrossFileResolver(files, symbolTable, typeHierarchy) {
|
|
431
|
+
const table = symbolTable || new SymbolTable();
|
|
432
|
+
const hierarchy = typeHierarchy || new TypeHierarchyResolver();
|
|
433
|
+
const resolver = new CrossFileResolver(table, hierarchy);
|
|
434
|
+
for (const { ir, path } of files) {
|
|
435
|
+
resolver.addFile(path, ir);
|
|
436
|
+
}
|
|
437
|
+
return resolver;
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=cross-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-file.js","sourceRoot":"","sources":["../../src/resolution/cross-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-file resolution module
|
|
3
|
+
*
|
|
4
|
+
* Provides type hierarchy tracking, symbol table, and cross-file
|
|
5
|
+
* call resolution for multi-file analysis.
|
|
6
|
+
*/
|
|
7
|
+
export { TypeHierarchyResolver, createWithJdkTypes } from './type-hierarchy.js';
|
|
8
|
+
export type { TypeNode } from './type-hierarchy.js';
|
|
9
|
+
export { SymbolTable, buildSymbolTable } from './symbol-table.js';
|
|
10
|
+
export type { ExportedSymbol } from './symbol-table.js';
|
|
11
|
+
export { CrossFileResolver, buildCrossFileResolver } from './cross-file.js';
|
|
12
|
+
export type { ResolvedCall, MethodTaintInfo, CrossFileTaintFlow, } from './cross-file.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-file resolution module
|
|
3
|
+
*
|
|
4
|
+
* Provides type hierarchy tracking, symbol table, and cross-file
|
|
5
|
+
* call resolution for multi-file analysis.
|
|
6
|
+
*/
|
|
7
|
+
export { TypeHierarchyResolver, createWithJdkTypes } from './type-hierarchy.js';
|
|
8
|
+
export { SymbolTable, buildSymbolTable } from './symbol-table.js';
|
|
9
|
+
export { CrossFileResolver, buildCrossFileResolver } from './cross-file.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resolution/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAElE,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbol Table for Cross-File Resolution
|
|
3
|
+
*
|
|
4
|
+
* Tracks what each file exports (classes, methods, fields) and imports,
|
|
5
|
+
* enabling resolution of cross-file references.
|
|
6
|
+
*/
|
|
7
|
+
import type { CircleIR, ImportInfo } from '../types/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Exported symbol with full metadata
|
|
10
|
+
*/
|
|
11
|
+
export interface ExportedSymbol {
|
|
12
|
+
name: string;
|
|
13
|
+
fqn: string;
|
|
14
|
+
kind: 'class' | 'interface' | 'enum' | 'method' | 'field';
|
|
15
|
+
file: string;
|
|
16
|
+
line: number;
|
|
17
|
+
visibility: 'public' | 'protected' | 'package' | 'private';
|
|
18
|
+
parentType?: string;
|
|
19
|
+
signature?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* SymbolTable - Tracks exports and imports across project files
|
|
23
|
+
*/
|
|
24
|
+
export declare class SymbolTable {
|
|
25
|
+
private exports;
|
|
26
|
+
private nameToFqns;
|
|
27
|
+
private fileImports;
|
|
28
|
+
private packageTypes;
|
|
29
|
+
private fqnToFile;
|
|
30
|
+
/**
|
|
31
|
+
* Add exports and imports from a CircleIR analysis result
|
|
32
|
+
*/
|
|
33
|
+
addFromIR(ir: CircleIR, filePath: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Add type and its members as exports
|
|
36
|
+
*/
|
|
37
|
+
private addTypeExports;
|
|
38
|
+
/**
|
|
39
|
+
* Add a method as an export
|
|
40
|
+
*/
|
|
41
|
+
private addMethodExport;
|
|
42
|
+
/**
|
|
43
|
+
* Add a field as an export
|
|
44
|
+
*/
|
|
45
|
+
private addFieldExport;
|
|
46
|
+
/**
|
|
47
|
+
* Register an export in all indexes
|
|
48
|
+
*/
|
|
49
|
+
private registerExport;
|
|
50
|
+
/**
|
|
51
|
+
* Add imports for a file
|
|
52
|
+
*/
|
|
53
|
+
private addFileImports;
|
|
54
|
+
/**
|
|
55
|
+
* Add explicit export declaration
|
|
56
|
+
*/
|
|
57
|
+
private addExplicitExport;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a simple name to its FQN from a given file's context
|
|
60
|
+
*/
|
|
61
|
+
resolveSymbol(name: string, fromFile: string): ExportedSymbol | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Resolve a type name to FQN, considering imports
|
|
64
|
+
*/
|
|
65
|
+
resolveTypeName(name: string, fromFile: string): string | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Get all methods of a type by FQN
|
|
68
|
+
*/
|
|
69
|
+
getMethodsOfType(typeFqn: string): ExportedSymbol[];
|
|
70
|
+
/**
|
|
71
|
+
* Find a method by name in a type
|
|
72
|
+
*/
|
|
73
|
+
findMethod(typeFqn: string, methodName: string): ExportedSymbol | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Get the file where a symbol is defined
|
|
76
|
+
*/
|
|
77
|
+
getFile(fqn: string): string | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Get all exported symbols from a file
|
|
80
|
+
*/
|
|
81
|
+
getFileExports(filePath: string): ExportedSymbol[];
|
|
82
|
+
/**
|
|
83
|
+
* Get all types in a package
|
|
84
|
+
*/
|
|
85
|
+
getPackageTypes(packageName: string): string[];
|
|
86
|
+
/**
|
|
87
|
+
* Get all known packages
|
|
88
|
+
*/
|
|
89
|
+
getPackages(): string[];
|
|
90
|
+
/**
|
|
91
|
+
* Check if a symbol exists
|
|
92
|
+
*/
|
|
93
|
+
hasSymbol(fqn: string): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Get symbol by FQN
|
|
96
|
+
*/
|
|
97
|
+
getSymbol(fqn: string): ExportedSymbol | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* Get all possible FQNs for a simple name
|
|
100
|
+
*/
|
|
101
|
+
getPossibleFqns(simpleName: string): string[];
|
|
102
|
+
/**
|
|
103
|
+
* Get imports for a file
|
|
104
|
+
*/
|
|
105
|
+
getFileImports(filePath: string): ImportInfo[];
|
|
106
|
+
/**
|
|
107
|
+
* Get statistics
|
|
108
|
+
*/
|
|
109
|
+
getStats(): {
|
|
110
|
+
totalSymbols: number;
|
|
111
|
+
types: number;
|
|
112
|
+
methods: number;
|
|
113
|
+
fields: number;
|
|
114
|
+
files: number;
|
|
115
|
+
packages: number;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Clear all data
|
|
119
|
+
*/
|
|
120
|
+
clear(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Extract visibility from annotations (for types)
|
|
123
|
+
*/
|
|
124
|
+
private getVisibility;
|
|
125
|
+
/**
|
|
126
|
+
* Extract visibility from modifiers
|
|
127
|
+
*/
|
|
128
|
+
private getVisibilityFromModifiers;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Build a symbol table from multiple IR results
|
|
132
|
+
*/
|
|
133
|
+
export declare function buildSymbolTable(files: Array<{
|
|
134
|
+
ir: CircleIR;
|
|
135
|
+
path: string;
|
|
136
|
+
}>): SymbolTable;
|