circle-ir 4.11.0 → 4.13.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.
Files changed (40) hide show
  1. package/README.md +9 -9
  2. package/dist/analysis/config-loader.d.ts.map +1 -1
  3. package/dist/analysis/config-loader.js +8 -2
  4. package/dist/analysis/config-loader.js.map +1 -1
  5. package/dist/analysis/constant-propagation/propagator.d.ts +2 -0
  6. package/dist/analysis/constant-propagation/propagator.d.ts.map +1 -1
  7. package/dist/analysis/constant-propagation/propagator.js +56 -2
  8. package/dist/analysis/constant-propagation/propagator.js.map +1 -1
  9. package/dist/analysis/entry-point-detection.d.ts +7 -0
  10. package/dist/analysis/entry-point-detection.d.ts.map +1 -1
  11. package/dist/analysis/entry-point-detection.js +13 -1
  12. package/dist/analysis/entry-point-detection.js.map +1 -1
  13. package/dist/analysis/interprocedural.d.ts.map +1 -1
  14. package/dist/analysis/interprocedural.js +4 -0
  15. package/dist/analysis/interprocedural.js.map +1 -1
  16. package/dist/analysis/passes/csharp-sanitizer-credit.d.ts +147 -0
  17. package/dist/analysis/passes/csharp-sanitizer-credit.d.ts.map +1 -0
  18. package/dist/analysis/passes/csharp-sanitizer-credit.js +564 -0
  19. package/dist/analysis/passes/csharp-sanitizer-credit.js.map +1 -0
  20. package/dist/analysis/passes/interprocedural-pass.d.ts.map +1 -1
  21. package/dist/analysis/passes/interprocedural-pass.js +89 -0
  22. package/dist/analysis/passes/interprocedural-pass.js.map +1 -1
  23. package/dist/analysis/passes/language-sources-pass.d.ts +6 -1
  24. package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
  25. package/dist/analysis/passes/language-sources-pass.js +15 -2
  26. package/dist/analysis/passes/language-sources-pass.js.map +1 -1
  27. package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
  28. package/dist/analysis/passes/sink-filter-pass.js +49 -52
  29. package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
  30. package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
  31. package/dist/analysis/passes/taint-propagation-pass.js +348 -16
  32. package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
  33. package/dist/analysis/require-entry-path.js +50 -4
  34. package/dist/analysis/require-entry-path.js.map +1 -1
  35. package/dist/browser/circle-ir.js +861 -65
  36. package/dist/core/circle-ir-core.cjs +81 -4
  37. package/dist/core/circle-ir-core.js +81 -4
  38. package/dist/core/extractors/dfg.js +49 -0
  39. package/dist/core/extractors/dfg.js.map +1 -1
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -9,7 +9,7 @@ A high-performance Static Application Security Testing (SAST) library for detect
9
9
 
10
10
  - **Taint Analysis**: Track data flow from sources (user input) to sinks (dangerous operations)
11
11
  - **Multi-language Support**: Java, JavaScript/TypeScript, Python, Go, Rust, Bash/Shell, HTML, and **C#/.NET (experimental)**
12
- - **High Accuracy**: 100% on OWASP Benchmark, 100% on Juliet Test Suite, 97.7% TPR on SecuriBench Micro
12
+ - **Measured accuracy** (cognium-dev 4.12.0): OWASP BenchmarkJava 90.0% TPR / 3.0% FPR on all 2,740 cases, SecuriBench Micro 88.0% / 6.7%; see [Benchmark Results](#benchmark-results)
13
13
  - **36-Pass Pipeline**: 19 security taint passes + 17 reliability/performance/maintainability/architecture quality passes
14
14
  - **Metrics Engine**: 24 software quality metrics (cyclomatic complexity, Halstead, CBO, RFC, LCOM, DIT, and 4 composite scores)
15
15
  - **Cross-File Analysis**: `analyzeProject()` surfaces taint flows that span multiple files
@@ -416,15 +416,15 @@ interface FileMetrics {
416
416
 
417
417
  ## Benchmark Results
418
418
 
419
- All scores below are for **circle-ir static analysis only** (no LLM).
419
+ Measured through cognium-dev **4.12.0** (circle-ir 4.12.0), static analysis only. Rules and commands: [`bench/README.md`](https://github.com/cogniumhq/cognium-dev/blob/main/bench/README.md#sast-accuracy-benchsast).
420
420
 
421
- | Benchmark | Score | Details |
422
- |-----------|-------|---------|
423
- | **OWASP Benchmark** | +100% | TPR 100%, FPR 0% (1415 test cases) |
424
- | **Juliet Test Suite** | +100% | 156/156 test cases, 9 CWEs |
425
- | **SecuriBench Micro** | 97.7% TPR | 105/108 vulns detected, 6.7% FPR |
426
- | **CWE-Bench-Java** | 42.5% | 51/120 real-world CVEs (vs CodeQL 22.5%, IRIS+GPT-4 45.8%) |
427
- | **Bash Synthetic** | 68.2% TPR | 15 TP, 9 TN, 0 FP on 31 synthetic test cases |
421
+ | Benchmark | TPR | FPR | Scope and rule |
422
+ |-----------|-----|-----|----------------|
423
+ | **OWASP BenchmarkJava 1.2** | 90.0% | 3.0% | All 2,740 cases; scorecard rule |
424
+ | **Juliet Test Suite 1.3** | 99.4% | 21.9% | `_01` cases of 9 injection CWEs; method level; `require-entry-path` disabled |
425
+ | **SecuriBench Micro** | 88.0% | 6.7% | 123 annotated cases |
426
+ | **CWE-Bench-Java** | 32.5% (39/120) | n/a | 120 real CVEs; a finding of the CVE's CWE inside the fix method |
427
+ | **Bash Synthetic** | 68.2% | 0% | 31 synthetic cases; April 2026 snapshot, not re-measured |
428
428
 
429
429
  ## Documentation
430
430
 
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/analysis/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,UAAU,EACX,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAEjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAiB1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG;IACtD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC,CAcA;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,mBAAmB,EAAE,GAC7B,kBAAkB,EAAE,CAQtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EAAE,EACxB,YAAY,EAAE,MAAM,EAAE,EACtB,qBAAqB,GAAE,MAAM,EAAO,GACnC,WAAW,CAYb;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,EAy0B1C,CAAC;AA+KF,eAAO,MAAM,aAAa,EAAE,WAAW,EA2qEtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAgjBhD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,EAiDtD,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAO9C;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,UAAU,EA8F5C,CAAC"}
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/analysis/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,UAAU,EACX,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAEjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAiB1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG;IACtD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC,CAcA;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,mBAAmB,EAAE,GAC7B,kBAAkB,EAAE,CAQtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EAAE,EACxB,YAAY,EAAE,MAAM,EAAE,EACtB,qBAAqB,GAAE,MAAM,EAAO,GACnC,WAAW,CAYb;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,EA00B1C,CAAC;AA+KF,eAAO,MAAM,aAAa,EAAE,WAAW,EAgrEtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAgjBhD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,EAiDtD,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAO9C;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,UAAU,EA8F5C,CAAC"}
@@ -325,6 +325,7 @@ export const DEFAULT_SOURCES = [
325
325
  { method: 'get', class: 'ConcurrentHashMap', type: 'plugin_param', severity: 'high', return_tainted: true },
326
326
  { method: 'get', class: 'Hashtable', type: 'plugin_param', severity: 'high', return_tainted: true },
327
327
  { method: 'get', class: 'Properties', type: 'config_param', severity: 'high', return_tainted: true },
328
+ { method: 'getProperty', class: 'Properties', type: 'config_param', severity: 'high', return_tainted: true },
328
329
  // Message/Event sources
329
330
  { method: 'getText', class: 'Message', type: 'io_input', severity: 'high', return_tainted: true },
330
331
  { method: 'getPayload', type: 'io_input', severity: 'high', return_tainted: true },
@@ -1348,8 +1349,13 @@ export const DEFAULT_SINKS = [
1348
1349
  { method: 'write', class: 'PrintWriter', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0] },
1349
1350
  { method: 'println', class: 'PrintWriter', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0] },
1350
1351
  { method: 'print', class: 'PrintWriter', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0] },
1351
- { method: 'format', class: 'PrintWriter', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0, 1] },
1352
- { method: 'printf', class: 'PrintWriter', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0, 1] },
1352
+ // format/printf take `(String fmt, Object... args)` or `(Locale l, String
1353
+ // fmt, Object... args)`. Every argument after the format can reach the page,
1354
+ // and the Locale overload shifts them all one place right, so `[0, 1]` missed
1355
+ // `printf(Locale.US, "%s", tainted)` and any second vararg. Enumerated, not
1356
+ // `[]` — see the ProcessBuilder note above.
1357
+ { method: 'format', class: 'PrintWriter', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0, 1, 2, 3, 4, 5, 6, 7] },
1358
+ { method: 'printf', class: 'PrintWriter', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0, 1, 2, 3, 4, 5, 6, 7] },
1353
1359
  // ServletOutputStream
1354
1360
  { method: 'write', class: 'ServletOutputStream', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0] },
1355
1361
  { method: 'print', class: 'ServletOutputStream', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0] },