circle-ir 3.9.8 → 3.9.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/analysis/passes/broad-catch-pass.d.ts +29 -0
  2. package/dist/analysis/passes/broad-catch-pass.js +79 -0
  3. package/dist/analysis/passes/broad-catch-pass.js.map +1 -0
  4. package/dist/analysis/passes/double-close-pass.d.ts +33 -0
  5. package/dist/analysis/passes/double-close-pass.js +109 -0
  6. package/dist/analysis/passes/double-close-pass.js.map +1 -0
  7. package/dist/analysis/passes/sink-filter-pass.js +7 -1
  8. package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
  9. package/dist/analysis/passes/swallowed-exception-pass.d.ts +35 -0
  10. package/dist/analysis/passes/swallowed-exception-pass.js +103 -0
  11. package/dist/analysis/passes/swallowed-exception-pass.js.map +1 -0
  12. package/dist/analysis/passes/unhandled-exception-pass.d.ts +34 -0
  13. package/dist/analysis/passes/unhandled-exception-pass.js +123 -0
  14. package/dist/analysis/passes/unhandled-exception-pass.js.map +1 -0
  15. package/dist/analysis/passes/use-after-close-pass.d.ts +30 -0
  16. package/dist/analysis/passes/use-after-close-pass.js +100 -0
  17. package/dist/analysis/passes/use-after-close-pass.js.map +1 -0
  18. package/dist/analysis/taint-matcher.js +1 -0
  19. package/dist/analysis/taint-matcher.js.map +1 -1
  20. package/dist/analyzer.d.ts +8 -3
  21. package/dist/analyzer.js +18 -3
  22. package/dist/analyzer.js.map +1 -1
  23. package/dist/browser/circle-ir.js +495 -3
  24. package/dist/core/circle-ir-core.cjs +2 -1
  25. package/dist/core/circle-ir-core.js +2 -1
  26. package/dist/graph/exception-flow-graph.d.ts +44 -0
  27. package/dist/graph/exception-flow-graph.js +75 -0
  28. package/dist/graph/exception-flow-graph.js.map +1 -0
  29. package/dist/graph/index.d.ts +1 -0
  30. package/dist/graph/index.js +1 -0
  31. package/dist/graph/index.js.map +1 -1
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.js +1 -0
  34. package/dist/index.js.map +1 -1
  35. package/package.json +1 -1
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Pass #29: broad-catch (CWE-396, category: reliability)
3
+ *
4
+ * Detects catch clauses that catch a base exception type (Exception,
5
+ * Throwable, BaseException) rather than the specific subtypes the code
6
+ * can handle. Broad catches suppress unexpected errors, make bugs harder
7
+ * to find, and can inadvertently catch serious errors (OutOfMemoryError,
8
+ * StackOverflowError) that should not be swallowed.
9
+ *
10
+ * Detection strategy:
11
+ * 1. Build an ExceptionFlowGraph to locate catch handler entry lines.
12
+ * 2. Check the source text of each catch line for broad-catch patterns.
13
+ *
14
+ * Languages: Java, Python only.
15
+ * - JS/TS: no typed catch clauses; not applicable.
16
+ * - Rust/Bash: no traditional exceptions; skip.
17
+ */
18
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
19
+ export interface BroadCatchResult {
20
+ broadCatches: Array<{
21
+ line: number;
22
+ type: string;
23
+ }>;
24
+ }
25
+ export declare class BroadCatchPass implements AnalysisPass<BroadCatchResult> {
26
+ readonly name = "broad-catch";
27
+ readonly category: "reliability";
28
+ run(ctx: PassContext): BroadCatchResult;
29
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Pass #29: broad-catch (CWE-396, category: reliability)
3
+ *
4
+ * Detects catch clauses that catch a base exception type (Exception,
5
+ * Throwable, BaseException) rather than the specific subtypes the code
6
+ * can handle. Broad catches suppress unexpected errors, make bugs harder
7
+ * to find, and can inadvertently catch serious errors (OutOfMemoryError,
8
+ * StackOverflowError) that should not be swallowed.
9
+ *
10
+ * Detection strategy:
11
+ * 1. Build an ExceptionFlowGraph to locate catch handler entry lines.
12
+ * 2. Check the source text of each catch line for broad-catch patterns.
13
+ *
14
+ * Languages: Java, Python only.
15
+ * - JS/TS: no typed catch clauses; not applicable.
16
+ * - Rust/Bash: no traditional exceptions; skip.
17
+ */
18
+ import { ExceptionFlowGraph } from '../../graph/exception-flow-graph.js';
19
+ /** Java: catch(Exception|Throwable|RuntimeException|Error ...) */
20
+ const JAVA_BROAD_RE = /catch\s*\(\s*(Exception|Throwable|RuntimeException|Error)\s/;
21
+ /**
22
+ * Python: bare `except:` or `except Exception[/BaseException][:]`
23
+ * Also matches `except (Exception, ...):` patterns.
24
+ */
25
+ const PYTHON_BROAD_RE = /^\s*except\s*:|except\s+(Exception|BaseException)\b/;
26
+ export class BroadCatchPass {
27
+ name = 'broad-catch';
28
+ category = 'reliability';
29
+ run(ctx) {
30
+ const { graph, code, language } = ctx;
31
+ if (language !== 'java' && language !== 'python') {
32
+ return { broadCatches: [] };
33
+ }
34
+ const { cfg } = graph.ir;
35
+ if (cfg.blocks.length === 0)
36
+ return { broadCatches: [] };
37
+ const exGraph = new ExceptionFlowGraph(cfg, graph.blockById);
38
+ if (!exGraph.hasTryCatch)
39
+ return { broadCatches: [] };
40
+ const file = graph.ir.meta.file;
41
+ const codeLines = code.split('\n');
42
+ const broadCatches = [];
43
+ const reported = new Set();
44
+ const pattern = language === 'java' ? JAVA_BROAD_RE : PYTHON_BROAD_RE;
45
+ for (const pair of exGraph.pairs) {
46
+ const catchLine = pair.catchBlock.start_line;
47
+ if (reported.has(catchLine))
48
+ continue;
49
+ const lineText = codeLines[catchLine - 1] ?? '';
50
+ const match = pattern.exec(lineText);
51
+ if (!match)
52
+ continue;
53
+ const caughtType = match[1] ?? 'Exception';
54
+ reported.add(catchLine);
55
+ broadCatches.push({ line: catchLine, type: caughtType });
56
+ const snippet = lineText.trim();
57
+ ctx.addFinding({
58
+ id: `broad-catch-${file}-${catchLine}`,
59
+ pass: this.name,
60
+ category: this.category,
61
+ rule_id: this.name,
62
+ cwe: 'CWE-396',
63
+ severity: 'low',
64
+ level: 'warning',
65
+ message: `Broad catch: catching \`${caughtType}\` at line ${catchLine} suppresses ` +
66
+ `unexpected errors and hides bugs`,
67
+ file,
68
+ line: catchLine,
69
+ snippet,
70
+ fix: language === 'java'
71
+ ? `Catch the specific exception types your code can handle (e.g., \`IOException\`, \`SQLException\`)`
72
+ : `Catch the specific exception types your code can handle (e.g., \`ValueError\`, \`KeyError\`)`,
73
+ evidence: { caughtType },
74
+ });
75
+ }
76
+ return { broadCatches };
77
+ }
78
+ }
79
+ //# sourceMappingURL=broad-catch-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broad-catch-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/broad-catch-pass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Pass #31: double-close (CWE-675, category: reliability)
3
+ *
4
+ * Detects I/O resources that are closed more than once within the same
5
+ * method. Calling close() on an already-closed stream (e.g., Java's
6
+ * FileInputStream, Node.js streams) typically throws an exception and
7
+ * indicates a resource-management bug.
8
+ *
9
+ * Detection strategy:
10
+ * 1. Find resource-opening calls (same patterns as resource-leak-pass).
11
+ * 2. Collect the bound variable from DFG defs at the open line.
12
+ * 3. Find ALL close() calls on that variable within the enclosing method.
13
+ * 4. If two or more close calls exist:
14
+ * a. Skip if both are inside a finally block (benign idiomatic pattern).
15
+ * b. Otherwise emit a finding.
16
+ *
17
+ * Languages: Java, JavaScript, TypeScript, Python, Rust (skip Bash).
18
+ */
19
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
20
+ export interface DoubleCloseResult {
21
+ doubleCloses: Array<{
22
+ openLine: number;
23
+ closeLines: number[];
24
+ variable: string;
25
+ }>;
26
+ }
27
+ export declare class DoubleClosePass implements AnalysisPass<DoubleCloseResult> {
28
+ readonly name = "double-close";
29
+ readonly category: "reliability";
30
+ run(ctx: PassContext): DoubleCloseResult;
31
+ /** True if the given line is inside a `finally` block in the method. */
32
+ private isInFinallyBlock;
33
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Pass #31: double-close (CWE-675, category: reliability)
3
+ *
4
+ * Detects I/O resources that are closed more than once within the same
5
+ * method. Calling close() on an already-closed stream (e.g., Java's
6
+ * FileInputStream, Node.js streams) typically throws an exception and
7
+ * indicates a resource-management bug.
8
+ *
9
+ * Detection strategy:
10
+ * 1. Find resource-opening calls (same patterns as resource-leak-pass).
11
+ * 2. Collect the bound variable from DFG defs at the open line.
12
+ * 3. Find ALL close() calls on that variable within the enclosing method.
13
+ * 4. If two or more close calls exist:
14
+ * a. Skip if both are inside a finally block (benign idiomatic pattern).
15
+ * b. Otherwise emit a finding.
16
+ *
17
+ * Languages: Java, JavaScript, TypeScript, Python, Rust (skip Bash).
18
+ */
19
+ /** Constructors that produce closeable resources. */
20
+ const RESOURCE_CTORS = new Set([
21
+ 'FileInputStream', 'FileOutputStream', 'FileReader', 'FileWriter',
22
+ 'BufferedReader', 'BufferedWriter', 'PrintWriter', 'InputStreamReader',
23
+ 'OutputStreamWriter', 'RandomAccessFile', 'DataInputStream', 'DataOutputStream',
24
+ 'ObjectInputStream', 'ObjectOutputStream', 'ZipInputStream', 'ZipOutputStream',
25
+ 'JarInputStream', 'JarOutputStream', 'GZIPInputStream', 'GZIPOutputStream',
26
+ 'FileChannel', 'Socket', 'ServerSocket', 'DatagramSocket',
27
+ ]);
28
+ /** Factory / open methods that return closeable resources. */
29
+ const RESOURCE_FACTORY_METHODS = new Set([
30
+ 'openConnection', 'openStream', 'newInputStream', 'newOutputStream',
31
+ 'newBufferedReader', 'newBufferedWriter', 'newByteChannel',
32
+ 'open', 'createReadStream', 'createWriteStream', 'createConnection',
33
+ ]);
34
+ /** Methods that release a resource. */
35
+ const CLOSE_METHODS = new Set([
36
+ 'close', 'dispose', 'shutdown', 'disconnect', 'release', 'destroy', 'free',
37
+ 'shutdownNow', 'terminate',
38
+ ]);
39
+ export class DoubleClosePass {
40
+ name = 'double-close';
41
+ category = 'reliability';
42
+ run(ctx) {
43
+ const { graph, code } = ctx;
44
+ if (ctx.language === 'bash')
45
+ return { doubleCloses: [] };
46
+ const file = graph.ir.meta.file;
47
+ const codeLines = code.split('\n');
48
+ const doubleCloses = [];
49
+ for (const call of graph.ir.calls) {
50
+ const name = call.method_name;
51
+ const isConstructor = call.is_constructor === true && RESOURCE_CTORS.has(name);
52
+ const isFactory = !call.is_constructor && RESOURCE_FACTORY_METHODS.has(name);
53
+ if (!isConstructor && !isFactory)
54
+ continue;
55
+ const openLine = call.location.line;
56
+ const defs = graph.defsAtLine(openLine);
57
+ if (defs.length === 0)
58
+ continue;
59
+ const resourceVar = defs[0].variable;
60
+ const methodInfo = graph.methodAtLine(openLine);
61
+ if (!methodInfo)
62
+ continue;
63
+ const { start_line: methodStart, end_line: methodEnd } = methodInfo.method;
64
+ // Collect all close calls on resourceVar within the method
65
+ const closeCalls = graph.ir.calls.filter(c => CLOSE_METHODS.has(c.method_name) &&
66
+ c.receiver === resourceVar &&
67
+ c.location.line > openLine &&
68
+ c.location.line <= methodEnd);
69
+ if (closeCalls.length < 2)
70
+ continue;
71
+ const closeLines = closeCalls.map(c => c.location.line);
72
+ // Benign check: skip if all closes are guarded by finally
73
+ // (common idiom: try { ... } finally { res.close(); } + catch { res.close(); })
74
+ const allInFinally = closeLines.every(cl => this.isInFinallyBlock(codeLines, cl, methodStart, methodEnd));
75
+ if (allInFinally)
76
+ continue;
77
+ doubleCloses.push({ openLine, closeLines, variable: resourceVar });
78
+ const snippet = (codeLines[openLine - 1] ?? '').trim();
79
+ const linesStr = closeLines.join(' and ');
80
+ ctx.addFinding({
81
+ id: `double-close-${file}-${openLine}`,
82
+ pass: this.name,
83
+ category: this.category,
84
+ rule_id: this.name,
85
+ cwe: 'CWE-675',
86
+ severity: 'medium',
87
+ level: 'warning',
88
+ message: `Double close: \`${resourceVar}\` is closed at lines ${linesStr} — ` +
89
+ `closing an already-closed resource may throw`,
90
+ file,
91
+ line: openLine,
92
+ snippet,
93
+ fix: `Close the resource exactly once in a finally block; ` +
94
+ `add a null/isClosed guard before the second close if closing on multiple paths`,
95
+ evidence: { variable: resourceVar, close_lines: closeLines },
96
+ });
97
+ }
98
+ return { doubleCloses };
99
+ }
100
+ /** True if the given line is inside a `finally` block in the method. */
101
+ isInFinallyBlock(lines, targetLine, methodStart, methodEnd) {
102
+ for (let ln = methodStart; ln <= targetLine && ln <= methodEnd && ln <= lines.length; ln++) {
103
+ if (/\bfinally\b/.test(lines[ln - 1] ?? ''))
104
+ return true;
105
+ }
106
+ return false;
107
+ }
108
+ }
109
+ //# sourceMappingURL=double-close-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"double-close-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/double-close-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,qDAAqD;AACrD,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IAClD,iBAAiB,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY;IACjE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,mBAAmB;IACtE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,kBAAkB;IAC/E,mBAAmB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB;IAC9E,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB;IAC1E,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,gBAAgB;CAC1D,CAAC,CAAC;AAEH,8DAA8D;AAC9D,MAAM,wBAAwB,GAAwB,IAAI,GAAG,CAAC;IAC5D,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB;IACnE,mBAAmB,EAAE,mBAAmB,EAAE,gBAAgB;IAC1D,MAAM,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB;CACpE,CAAC,CAAC;AAEH,uCAAuC;AACvC,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC;IACjD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM;IAC1E,aAAa,EAAE,WAAW;CAC3B,CAAC,CAAC;AAMH,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,cAAc,CAAC;IACtB,QAAQ,GAAG,aAAsB,CAAC;IAE3C,GAAG,CAAC,GAAgB;QAClB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;QAE5B,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM;YAAE,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;QAEzD,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,YAAY,GAAsC,EAAE,CAAC;QAE3D,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;YAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,KAAK,IAAI,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/E,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7E,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS;gBAAE,SAAS;YAE3C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACpC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YACxC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAChC,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAErC,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAChD,IAAI,CAAC,UAAU;gBAAE,SAAS;YAC1B,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC;YAE3E,2DAA2D;YAC3D,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CACtC,CAAC,CAAC,EAAE,CACF,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;gBAChC,CAAC,CAAC,QAAQ,KAAK,WAAW;gBAC1B,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,QAAQ;gBAC1B,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,SAAS,CAC/B,CAAC;YAEF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAEpC,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAExD,0DAA0D;YAC1D,gFAAgF;YAChF,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CACzC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,SAAS,CAAC,CAC7D,CAAC;YACF,IAAI,YAAY;gBAAE,SAAS;YAE3B,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;YAEnE,MAAM,OAAO,GAAG,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACvD,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1C,GAAG,CAAC,UAAU,CAAC;gBACb,EAAE,EAAE,gBAAgB,IAAI,IAAI,QAAQ,EAAE;gBACtC,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,IAAI;gBAClB,GAAG,EAAE,SAAS;gBACd,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,SAAS;gBAChB,OAAO,EACL,mBAAmB,WAAW,yBAAyB,QAAQ,KAAK;oBACpE,8CAA8C;gBAChD,IAAI;gBACJ,IAAI,EAAE,QAAQ;gBACd,OAAO;gBACP,GAAG,EACD,sDAAsD;oBACtD,gFAAgF;gBAClF,QAAQ,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE;aAC7D,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,wEAAwE;IAChE,gBAAgB,CACtB,KAAe,EACf,UAAkB,EAClB,WAAmB,EACnB,SAAiB;QAEjB,KAAK,IAAI,EAAE,GAAG,WAAW,EAAE,EAAE,IAAI,UAAU,IAAI,EAAE,IAAI,SAAS,IAAI,EAAE,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;YAC3F,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC3D,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
@@ -148,7 +148,13 @@ export function filterCleanVariableSinks(sinks, calls, taintedVars, symbols, dfg
148
148
  return sinks.filter(sink => {
149
149
  const callsAtSink = callsByLine.get(sink.line) ?? [];
150
150
  const isInSynchronizedBlock = synchronizedLines?.has(sink.line) ?? false;
151
- for (const call of callsAtSink) {
151
+ // Only evaluate the call that matched the sink pattern — not nested inner calls at the
152
+ // same line (e.g. System.getProperty("user.dir") inside r.exec(args,...,new File(...))).
153
+ // sink.method is set by findSinks to call.method_name; language-sources sinks also carry it.
154
+ const relevantCalls = sink.method
155
+ ? callsAtSink.filter(c => c.method_name === sink.method)
156
+ : callsAtSink;
157
+ for (const call of relevantCalls) {
152
158
  let allArgsAreClean = true;
153
159
  const methodName = call.in_method;
154
160
  for (const arg of call.arguments) {
@@ -1 +1 @@
1
- {"version":3,"file":"sink-filter-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/sink-filter-pass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sink-filter-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/sink-filter-pass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Pass #28: swallowed-exception (CWE-390, category: reliability)
3
+ *
4
+ * Detects catch blocks that silently discard exceptions — no re-throw,
5
+ * no logging call, no error return. Swallowed exceptions hide failures,
6
+ * make debugging extremely difficult, and can mask security issues.
7
+ *
8
+ * Detection strategy:
9
+ * 1. Build an ExceptionFlowGraph from the CFG exception edges.
10
+ * 2. For each catch handler entry block, determine the catch body bounds
11
+ * using a brace-depth walk of the source text.
12
+ * 3. Scan the catch body for any "meaningful action": throw/raise,
13
+ * logging API call, or a non-empty return statement.
14
+ * 4. If nothing is found → emit a finding at the catch line.
15
+ *
16
+ * Languages: Java, JavaScript, TypeScript, Python (skip Rust/Bash).
17
+ */
18
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
19
+ export interface SwallowedExceptionResult {
20
+ swallowed: Array<{
21
+ line: number;
22
+ }>;
23
+ }
24
+ export declare class SwallowedExceptionPass implements AnalysisPass<SwallowedExceptionResult> {
25
+ readonly name = "swallowed-exception";
26
+ readonly category: "reliability";
27
+ run(ctx: PassContext): SwallowedExceptionResult;
28
+ /**
29
+ * Walks source lines starting at `startLine` counting brace depth.
30
+ * Returns the line where the brace depth first returns to zero after
31
+ * the opening brace (i.e., the closing brace of the catch block).
32
+ * Capped at `maxLine`.
33
+ */
34
+ private findCatchBodyEnd;
35
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Pass #28: swallowed-exception (CWE-390, category: reliability)
3
+ *
4
+ * Detects catch blocks that silently discard exceptions — no re-throw,
5
+ * no logging call, no error return. Swallowed exceptions hide failures,
6
+ * make debugging extremely difficult, and can mask security issues.
7
+ *
8
+ * Detection strategy:
9
+ * 1. Build an ExceptionFlowGraph from the CFG exception edges.
10
+ * 2. For each catch handler entry block, determine the catch body bounds
11
+ * using a brace-depth walk of the source text.
12
+ * 3. Scan the catch body for any "meaningful action": throw/raise,
13
+ * logging API call, or a non-empty return statement.
14
+ * 4. If nothing is found → emit a finding at the catch line.
15
+ *
16
+ * Languages: Java, JavaScript, TypeScript, Python (skip Rust/Bash).
17
+ */
18
+ import { ExceptionFlowGraph } from '../../graph/exception-flow-graph.js';
19
+ const MEANINGFUL_ACTION_RE = /\b(throw|raise|log|logger|console\.(error|warn|log|debug|info)|System\.(out|err)\.|print(?:ln|f)?|warn|error|debug|info|fatal|LOGGER|LOG|logging\.(warning|error|debug|info|critical))\b|\breturn\s+\S/;
20
+ export class SwallowedExceptionPass {
21
+ name = 'swallowed-exception';
22
+ category = 'reliability';
23
+ run(ctx) {
24
+ const { graph, code, language } = ctx;
25
+ if (language === 'rust' || language === 'bash') {
26
+ return { swallowed: [] };
27
+ }
28
+ const { cfg } = graph.ir;
29
+ if (cfg.blocks.length === 0)
30
+ return { swallowed: [] };
31
+ const exGraph = new ExceptionFlowGraph(cfg, graph.blockById);
32
+ if (!exGraph.hasTryCatch)
33
+ return { swallowed: [] };
34
+ const file = graph.ir.meta.file;
35
+ const codeLines = code.split('\n');
36
+ const swallowed = [];
37
+ const reported = new Set();
38
+ for (const pair of exGraph.pairs) {
39
+ const catchLine = pair.catchBlock.start_line;
40
+ if (reported.has(catchLine))
41
+ continue;
42
+ // Determine catch body end via brace-depth walk
43
+ const methodInfo = graph.methodAtLine(catchLine);
44
+ const scanEnd = methodInfo ? methodInfo.method.end_line : codeLines.length;
45
+ const catchBodyEnd = this.findCatchBodyEnd(codeLines, catchLine, scanEnd);
46
+ // Scan for any meaningful action
47
+ let hasAction = false;
48
+ for (let ln = catchLine; ln <= catchBodyEnd && ln <= codeLines.length; ln++) {
49
+ if (MEANINGFUL_ACTION_RE.test(codeLines[ln - 1] ?? '')) {
50
+ hasAction = true;
51
+ break;
52
+ }
53
+ }
54
+ if (!hasAction) {
55
+ reported.add(catchLine);
56
+ swallowed.push({ line: catchLine });
57
+ const snippet = (codeLines[catchLine - 1] ?? '').trim();
58
+ ctx.addFinding({
59
+ id: `swallowed-exception-${file}-${catchLine}`,
60
+ pass: this.name,
61
+ category: this.category,
62
+ rule_id: this.name,
63
+ cwe: 'CWE-390',
64
+ severity: 'medium',
65
+ level: 'warning',
66
+ message: `Swallowed exception: catch block at line ${catchLine} has no throw, log, or ` +
67
+ `return — the exception is silently discarded`,
68
+ file,
69
+ line: catchLine,
70
+ snippet,
71
+ fix: 'At minimum log the exception, or re-throw it; never silently discard exceptions',
72
+ });
73
+ }
74
+ }
75
+ return { swallowed };
76
+ }
77
+ /**
78
+ * Walks source lines starting at `startLine` counting brace depth.
79
+ * Returns the line where the brace depth first returns to zero after
80
+ * the opening brace (i.e., the closing brace of the catch block).
81
+ * Capped at `maxLine`.
82
+ */
83
+ findCatchBodyEnd(lines, startLine, maxLine) {
84
+ let depth = 0;
85
+ let started = false;
86
+ for (let ln = startLine; ln <= maxLine && ln <= lines.length; ln++) {
87
+ const text = lines[ln - 1] ?? '';
88
+ for (const ch of text) {
89
+ if (ch === '{') {
90
+ depth++;
91
+ started = true;
92
+ }
93
+ else if (ch === '}' && started) {
94
+ depth--;
95
+ }
96
+ }
97
+ if (started && depth <= 0)
98
+ return ln;
99
+ }
100
+ return maxLine;
101
+ }
102
+ }
103
+ //# sourceMappingURL=swallowed-exception-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swallowed-exception-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/swallowed-exception-pass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Pass #30: unhandled-exception (CWE-390, category: reliability)
3
+ *
4
+ * Detects explicit throw/raise statements that are not covered by any
5
+ * try/catch in the same function. Uncaught exceptions surface as
6
+ * unhandled-rejection crashes (Node.js) or propagate unexpectedly to
7
+ * callers who may not anticipate them.
8
+ *
9
+ * Detection strategy (conservative, low false-positive):
10
+ * 1. Build ExceptionFlowGraph. Derive "covered" line ranges as
11
+ * [tryBlock.start_line, catchBlock.start_line − 1] for each pair.
12
+ * 2. Scan source lines for explicit throw/raise keywords.
13
+ * 3. Skip if the throw line is already inside a catch block (re-throw).
14
+ * 4. Skip if the throw line falls within any covered range.
15
+ * 5. Emit one finding per enclosing method (avoid duplicate findings for
16
+ * multiple throws in the same uncovered method).
17
+ *
18
+ * Languages: JavaScript, TypeScript, Python only.
19
+ * - Java: checked exceptions are intentionally propagated via `throws`;
20
+ * too noisy without type hierarchy support.
21
+ * - Rust/Bash: no traditional throw/raise; skip.
22
+ */
23
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
24
+ export interface UnhandledExceptionResult {
25
+ unhandled: Array<{
26
+ line: number;
27
+ method: string;
28
+ }>;
29
+ }
30
+ export declare class UnhandledExceptionPass implements AnalysisPass<UnhandledExceptionResult> {
31
+ readonly name = "unhandled-exception";
32
+ readonly category: "reliability";
33
+ run(ctx: PassContext): UnhandledExceptionResult;
34
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Pass #30: unhandled-exception (CWE-390, category: reliability)
3
+ *
4
+ * Detects explicit throw/raise statements that are not covered by any
5
+ * try/catch in the same function. Uncaught exceptions surface as
6
+ * unhandled-rejection crashes (Node.js) or propagate unexpectedly to
7
+ * callers who may not anticipate them.
8
+ *
9
+ * Detection strategy (conservative, low false-positive):
10
+ * 1. Build ExceptionFlowGraph. Derive "covered" line ranges as
11
+ * [tryBlock.start_line, catchBlock.start_line − 1] for each pair.
12
+ * 2. Scan source lines for explicit throw/raise keywords.
13
+ * 3. Skip if the throw line is already inside a catch block (re-throw).
14
+ * 4. Skip if the throw line falls within any covered range.
15
+ * 5. Emit one finding per enclosing method (avoid duplicate findings for
16
+ * multiple throws in the same uncovered method).
17
+ *
18
+ * Languages: JavaScript, TypeScript, Python only.
19
+ * - Java: checked exceptions are intentionally propagated via `throws`;
20
+ * too noisy without type hierarchy support.
21
+ * - Rust/Bash: no traditional throw/raise; skip.
22
+ */
23
+ import { ExceptionFlowGraph } from '../../graph/exception-flow-graph.js';
24
+ const JS_THROW_RE = /^\s*throw\s+/;
25
+ const PYTHON_RAISE_RE = /^\s*raise\b/;
26
+ export class UnhandledExceptionPass {
27
+ name = 'unhandled-exception';
28
+ category = 'reliability';
29
+ run(ctx) {
30
+ const { graph, code, language } = ctx;
31
+ if (language !== 'javascript' && language !== 'typescript' && language !== 'python') {
32
+ return { unhandled: [] };
33
+ }
34
+ const { cfg } = graph.ir;
35
+ const file = graph.ir.meta.file;
36
+ const codeLines = code.split('\n');
37
+ const exGraph = new ExceptionFlowGraph(cfg, graph.blockById);
38
+ // Build covered ranges: [tryBlock.start_line, catchBlock.start_line - 1]
39
+ const coveredRanges = [];
40
+ for (const pair of exGraph.pairs) {
41
+ if (pair.catchBlock.start_line > pair.tryBlock.start_line) {
42
+ coveredRanges.push({
43
+ start: pair.tryBlock.start_line,
44
+ end: pair.catchBlock.start_line - 1,
45
+ });
46
+ }
47
+ }
48
+ // Collect catch-block start lines (to detect re-throws)
49
+ const catchStarts = new Set(exGraph.pairs.map(p => p.catchBlock.start_line));
50
+ const throwRe = language === 'python' ? PYTHON_RAISE_RE : JS_THROW_RE;
51
+ const unhandled = [];
52
+ const reportedMethods = new Set();
53
+ for (let ln = 1; ln <= codeLines.length; ln++) {
54
+ const lineText = codeLines[ln - 1] ?? '';
55
+ if (!throwRe.test(lineText))
56
+ continue;
57
+ // Skip re-throws inside catch blocks
58
+ let inCatch = false;
59
+ for (const cs of catchStarts) {
60
+ if (ln >= cs) {
61
+ inCatch = true;
62
+ break;
63
+ }
64
+ }
65
+ // More precise: only skip if ln is actually within a catch body
66
+ // (not just any line after a catch start). Use method boundary check.
67
+ // Simplified: if the line is >= any catch start within the same method, skip.
68
+ // Better heuristic: check if any pair has catchBlock.start_line <= ln
69
+ // and the throw is inside that catch body (ln <= methodEnd of that catch).
70
+ // We use a simple check: if the throw line is >= a catch start and
71
+ // the enclosing method contains the corresponding try, treat as re-throw.
72
+ inCatch = false;
73
+ for (const pair of exGraph.pairs) {
74
+ if (ln >= pair.catchBlock.start_line) {
75
+ // Check same method
76
+ const mThrow = graph.methodAtLine(ln);
77
+ const mCatch = graph.methodAtLine(pair.catchBlock.start_line);
78
+ if (mThrow &&
79
+ mCatch &&
80
+ mThrow.method.start_line === mCatch.method.start_line) {
81
+ inCatch = true;
82
+ break;
83
+ }
84
+ }
85
+ }
86
+ if (inCatch)
87
+ continue;
88
+ // Check if covered by a try/catch range
89
+ const isCovered = coveredRanges.some(r => ln >= r.start && ln <= r.end);
90
+ if (isCovered)
91
+ continue;
92
+ // Deduplicate by enclosing method
93
+ const methodInfo = graph.methodAtLine(ln);
94
+ const methodKey = methodInfo
95
+ ? `${methodInfo.method.start_line}-${methodInfo.method.end_line}`
96
+ : `global-${ln}`;
97
+ if (reportedMethods.has(methodKey))
98
+ continue;
99
+ reportedMethods.add(methodKey);
100
+ const methodName = methodInfo?.method.name ?? '<anonymous>';
101
+ unhandled.push({ line: ln, method: methodName });
102
+ const snippet = lineText.trim();
103
+ ctx.addFinding({
104
+ id: `unhandled-exception-${file}-${ln}`,
105
+ pass: this.name,
106
+ category: this.category,
107
+ rule_id: this.name,
108
+ cwe: 'CWE-390',
109
+ severity: 'medium',
110
+ level: 'warning',
111
+ message: `Unhandled exception: \`throw\` at line ${ln} in \`${methodName}\` is not inside ` +
112
+ `a try/catch — callers receive an unexpected exception`,
113
+ file,
114
+ line: ln,
115
+ snippet,
116
+ fix: 'Wrap throwing code in a try/catch, or document the exception in the function signature',
117
+ evidence: { method: methodName },
118
+ });
119
+ }
120
+ return { unhandled };
121
+ }
122
+ }
123
+ //# sourceMappingURL=unhandled-exception-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unhandled-exception-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/unhandled-exception-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE,MAAM,WAAW,GAAG,cAAc,CAAC;AACnC,MAAM,eAAe,GAAG,aAAa,CAAC;AAMtC,MAAM,OAAO,sBAAsB;IACxB,IAAI,GAAG,qBAAqB,CAAC;IAC7B,QAAQ,GAAG,aAAsB,CAAC;IAE3C,GAAG,CAAC,GAAgB;QAClB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;QAEtC,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACpF,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QAC3B,CAAC;QAED,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEnC,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAE7D,yEAAyE;QACzE,MAAM,aAAa,GAA0C,EAAE,CAAC;QAChE,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACjC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC1D,aAAa,CAAC,IAAI,CAAC;oBACjB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU;oBAC/B,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,CAAC;iBACpC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,MAAM,WAAW,GAAG,IAAI,GAAG,CACzB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAChD,CAAC;QAEF,MAAM,OAAO,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC;QAEtE,MAAM,SAAS,GAA0C,EAAE,CAAC;QAC5D,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;QAE1C,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAEtC,qCAAqC;YACrC,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;gBAC7B,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;oBAAC,OAAO,GAAG,IAAI,CAAC;oBAAC,MAAM;gBAAC,CAAC;YAC1C,CAAC;YACD,gEAAgE;YAChE,sEAAsE;YACtE,8EAA8E;YAC9E,sEAAsE;YACtE,2EAA2E;YAC3E,mEAAmE;YACnE,0EAA0E;YAC1E,OAAO,GAAG,KAAK,CAAC;YAChB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBACjC,IAAI,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;oBACrC,oBAAoB;oBACpB,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;oBACtC,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;oBAC9D,IACE,MAAM;wBACN,MAAM;wBACN,MAAM,CAAC,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,EACrD,CAAC;wBACD,OAAO,GAAG,IAAI,CAAC;wBACf,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,OAAO;gBAAE,SAAS;YAEtB,wCAAwC;YACxC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACxE,IAAI,SAAS;gBAAE,SAAS;YAExB,kCAAkC;YAClC,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAC1C,MAAM,SAAS,GAAG,UAAU;gBAC1B,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE;gBACjE,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC;YAEnB,IAAI,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC;gBAAE,SAAS;YAC7C,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAE/B,MAAM,UAAU,GAAG,UAAU,EAAE,MAAM,CAAC,IAAI,IAAI,aAAa,CAAC;YAC5D,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YAEjD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,GAAG,CAAC,UAAU,CAAC;gBACb,EAAE,EAAE,uBAAuB,IAAI,IAAI,EAAE,EAAE;gBACvC,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,IAAI;gBAClB,GAAG,EAAE,SAAS;gBACd,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,SAAS;gBAChB,OAAO,EACL,0CAA0C,EAAE,SAAS,UAAU,mBAAmB;oBAClF,uDAAuD;gBACzD,IAAI;gBACJ,IAAI,EAAE,EAAE;gBACR,OAAO;gBACP,GAAG,EAAE,wFAAwF;gBAC7F,QAAQ,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;aACjC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,SAAS,EAAE,CAAC;IACvB,CAAC;CACF"}