circle-ir 3.28.0 → 3.30.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/configs/sinks/path.yaml +6 -4
- package/configs/sources/http_sources.yaml +24 -0
- package/dist/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +83 -54
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/constant-propagation/patterns.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/patterns.js +14 -0
- package/dist/analysis/constant-propagation/patterns.js.map +1 -1
- package/dist/analysis/passes/taint-matcher-pass.js +1 -1
- package/dist/analysis/passes/taint-matcher-pass.js.map +1 -1
- package/dist/analysis/taint-matcher.d.ts +2 -2
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +27 -8
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/analyzer.js +1 -1
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +125 -65
- package/dist/core/circle-ir-core.cjs +123 -63
- package/dist/core/circle-ir-core.js +123 -63
- package/dist/types/config.d.ts +8 -1
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -9677,6 +9677,13 @@ var DEFAULT_SOURCES = [
|
|
|
9677
9677
|
{ method: "getContextPath", class: "HttpServletRequest", type: "http_path", severity: "medium", return_tainted: true },
|
|
9678
9678
|
{ method: "getRemoteHost", class: "HttpServletRequest", type: "http_header", severity: "medium", return_tainted: true },
|
|
9679
9679
|
{ method: "getRemoteAddr", class: "HttpServletRequest", type: "http_header", severity: "medium", return_tainted: true },
|
|
9680
|
+
// Apache Shiro WebUtils helpers — return URL-decoded request data. The internal
|
|
9681
|
+
// decodeRequestString → URLDecoder.decode chain can re-introduce ../ from
|
|
9682
|
+
// %2e%2e payloads that bypassed auth-time normalization. CVE-2023-34478,
|
|
9683
|
+
// CVE-2023-46749 (issue #8).
|
|
9684
|
+
{ method: "getPathWithinApplication", class: "WebUtils", type: "http_path", severity: "high", return_tainted: true },
|
|
9685
|
+
{ method: "getRequestUri", class: "WebUtils", type: "http_path", severity: "high", return_tainted: true },
|
|
9686
|
+
{ method: "decodeRequestString", class: "WebUtils", type: "http_path", severity: "high", return_tainted: true },
|
|
9680
9687
|
// Additional HTTP request methods that can be attacker-controlled
|
|
9681
9688
|
{ method: "getProtocol", class: "HttpServletRequest", type: "http_header", severity: "medium", return_tainted: true },
|
|
9682
9689
|
{ method: "getScheme", class: "HttpServletRequest", type: "http_header", severity: "medium", return_tainted: true },
|
|
@@ -10049,7 +10056,9 @@ var DEFAULT_SINKS = [
|
|
|
10049
10056
|
{ method: "ProcessBuilder", class: "constructor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10050
10057
|
{ method: "command", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10051
10058
|
// Commons Exec
|
|
10052
|
-
|
|
10059
|
+
// Note: bare class 'Executor' removed — it collided with java.util.concurrent.Executor
|
|
10060
|
+
// (Executor.execute(Runnable) is not command injection). Apache Commons Exec users
|
|
10061
|
+
// typically declare DefaultExecutor explicitly, so we match that instead. See issue #14.
|
|
10053
10062
|
{ method: "execute", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10054
10063
|
{ method: "CommandLine", class: "constructor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10055
10064
|
{ method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
@@ -10117,8 +10126,8 @@ var DEFAULT_SINKS = [
|
|
|
10117
10126
|
{ method: "popen", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10118
10127
|
{ method: "system", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10119
10128
|
// Apache Commons Exec
|
|
10120
|
-
|
|
10121
|
-
{ method: "setCommandline", class: "
|
|
10129
|
+
// Note: bare class 'Executor' removed (see comment above) — DefaultExecutor matched explicitly.
|
|
10130
|
+
{ method: "setCommandline", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10122
10131
|
{ method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10123
10132
|
{ method: "addArgument", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10124
10133
|
// Process-related utilities
|
|
@@ -10127,7 +10136,10 @@ var DEFAULT_SINKS = [
|
|
|
10127
10136
|
{ method: "redirectOutput", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "medium", arg_positions: [0] },
|
|
10128
10137
|
{ method: "redirectInput", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "medium", arg_positions: [0] },
|
|
10129
10138
|
// Path Traversal (CWE-22)
|
|
10130
|
-
|
|
10139
|
+
// File: covers both File(String pathname) and File(parent, child). The 2-arg
|
|
10140
|
+
// overload's child argument carries CVE-2018-8041 (Camel mail Content-Disposition
|
|
10141
|
+
// filename written to disk).
|
|
10142
|
+
{ method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
|
|
10131
10143
|
{ method: "FileInputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10132
10144
|
{ method: "FileOutputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10133
10145
|
{ method: "FileReader", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -10740,11 +10752,14 @@ var DEFAULT_SINKS = [
|
|
|
10740
10752
|
{ method: "spawn", class: "child_process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10741
10753
|
{ method: "spawnSync", class: "child_process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10742
10754
|
// Also match without receiver (destructured imports: const { exec } = require('child_process'))
|
|
10755
|
+
// `exec` is intentionally classless: catches Node.js child_process.exec AND
|
|
10756
|
+
// Java Runtime.exec (via `r.exec()` where heuristic can't resolve r → Runtime).
|
|
10743
10757
|
{ method: "exec", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
|
|
10744
|
-
|
|
10745
|
-
{ method: "
|
|
10746
|
-
{ method: "
|
|
10747
|
-
{ method: "
|
|
10758
|
+
// `execSync`/`spawn`/`spawnSync`/`execFile` are Node-specific — language-scope them.
|
|
10759
|
+
{ method: "execSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10760
|
+
{ method: "spawn", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10761
|
+
{ method: "spawnSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10762
|
+
{ method: "execFile", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10748
10763
|
// Node.js File System (path traversal)
|
|
10749
10764
|
{ method: "readFile", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10750
10765
|
{ method: "readFileSync", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
@@ -10757,12 +10772,15 @@ var DEFAULT_SINKS = [
|
|
|
10757
10772
|
{ method: "createReadStream", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10758
10773
|
{ method: "createWriteStream", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10759
10774
|
// Node.js SQL (mysql, pg, sqlite, etc.)
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
{ method: "query", class: "
|
|
10775
|
+
// Language-scoped: generic class names `Pool`/`Connection`/`Client` substring-match
|
|
10776
|
+
// unrelated Java identifiers like `cachedThreadPool`, `dbConnection`. See issue #14.
|
|
10777
|
+
{ method: "query", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10778
|
+
{ method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10779
|
+
{ method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10763
10780
|
// Note: classless { method: 'query' } removed — too many FPs (UriComponentsBuilder.query(), etc.)
|
|
10764
10781
|
// SQL query calls are covered by class-specific patterns above (Connection, Pool, Client, JdbcTemplate)
|
|
10765
|
-
|
|
10782
|
+
// Note: `raw` is shared with Python (Django ORM) — scoped to JS+TS to avoid leaking.
|
|
10783
|
+
{ method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10766
10784
|
// Browser DOM XSS sinks
|
|
10767
10785
|
{ method: "setAttribute", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [1] },
|
|
10768
10786
|
// Express.js XSS (response methods)
|
|
@@ -10772,7 +10790,7 @@ var DEFAULT_SINKS = [
|
|
|
10772
10790
|
{ method: "html", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10773
10791
|
{ method: "render", class: "Response", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [1] },
|
|
10774
10792
|
// Node.js Code Injection (eval, vm, etc.)
|
|
10775
|
-
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10793
|
+
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10776
10794
|
{ method: "Function", class: "constructor", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10777
10795
|
{ method: "runInContext", class: "vm", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10778
10796
|
{ method: "runInNewContext", class: "vm", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
@@ -10788,7 +10806,7 @@ var DEFAULT_SINKS = [
|
|
|
10788
10806
|
{ method: "get", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10789
10807
|
{ method: "post", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10790
10808
|
{ method: "request", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10791
|
-
{ method: "fetch", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10809
|
+
{ method: "fetch", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10792
10810
|
{ method: "request", class: "http", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10793
10811
|
{ method: "get", class: "http", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10794
10812
|
{ method: "request", class: "https", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
@@ -10817,10 +10835,12 @@ var DEFAULT_SINKS = [
|
|
|
10817
10835
|
{ method: "check_call", class: "subprocess", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10818
10836
|
{ method: "Popen", class: "subprocess", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10819
10837
|
// Python Code Injection
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
{ method: "
|
|
10823
|
-
{ method: "
|
|
10838
|
+
// Language-scoped: classless `exec`/`eval`/`compile` collide with Java/JS builtins
|
|
10839
|
+
// and Java util.concurrent (e.g. Executor.execute / future.compile).
|
|
10840
|
+
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10841
|
+
{ method: "exec", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10842
|
+
{ method: "compile", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10843
|
+
{ method: "__import__", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10824
10844
|
// Python Deserialization
|
|
10825
10845
|
{ method: "loads", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10826
10846
|
{ method: "load", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
@@ -10828,36 +10848,39 @@ var DEFAULT_SINKS = [
|
|
|
10828
10848
|
{ method: "load", class: "yaml", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10829
10849
|
{ method: "loads", class: "yaml", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10830
10850
|
// Python SQL Injection
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
{ method: "
|
|
10834
|
-
{ method: "
|
|
10851
|
+
// Language-scoped: classless `execute`/`raw` collide with Java util.concurrent
|
|
10852
|
+
// (Executor.execute, ThreadPool.execute) and other languages. See issue #14.
|
|
10853
|
+
{ method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10854
|
+
{ method: "executemany", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10855
|
+
{ method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10856
|
+
{ method: "extra", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10835
10857
|
// Python Path Traversal
|
|
10836
|
-
|
|
10858
|
+
// Language-scoped: classless `open` collides with Java I/O / JS DOM.
|
|
10859
|
+
{ method: "open", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10837
10860
|
{ method: "remove", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10838
10861
|
{ method: "unlink", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10839
10862
|
{ method: "rmdir", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10840
10863
|
{ method: "rmtree", class: "shutil", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10841
|
-
{ method: "send_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10864
|
+
{ method: "send_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10842
10865
|
// Python XSS / SSTI
|
|
10843
|
-
{ method: "render_template_string", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10844
|
-
{ method: "Markup", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10845
|
-
{ method: "mark_safe", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10866
|
+
{ method: "render_template_string", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10867
|
+
{ method: "Markup", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10868
|
+
{ method: "mark_safe", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10846
10869
|
// Python SSRF
|
|
10847
10870
|
{ method: "get", class: "requests", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10848
10871
|
{ method: "post", class: "requests", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10849
10872
|
{ method: "urlopen", class: "urllib.request", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10850
10873
|
// Python Open Redirect
|
|
10851
|
-
{ method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0] },
|
|
10874
|
+
{ method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["python"] },
|
|
10852
10875
|
// Python XPath Injection
|
|
10853
|
-
{ method: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10876
|
+
{ method: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10854
10877
|
{ method: "find", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10855
10878
|
{ method: "findall", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10856
10879
|
{ method: "iterfind", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10857
10880
|
{ method: "XPath", class: "lxml", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10858
10881
|
// elementpath library (XPath 2.0/3.0)
|
|
10859
10882
|
{ method: "select", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [1] },
|
|
10860
|
-
{ method: "select", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10883
|
+
{ method: "select", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10861
10884
|
{ method: "iter_select", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [1] },
|
|
10862
10885
|
{ method: "Selector", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10863
10886
|
// Python XXE
|
|
@@ -10949,36 +10972,42 @@ var DEFAULT_SINKS = [
|
|
|
10949
10972
|
{ method: "arg", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10950
10973
|
{ method: "args", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10951
10974
|
// Rust SQL Injection (sqlx, diesel, rusqlite, tokio-postgres)
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
{ method: "query", class: "
|
|
10955
|
-
{ method: "execute", class: "
|
|
10956
|
-
{ method: "
|
|
10957
|
-
{ method: "
|
|
10958
|
-
{ method: "
|
|
10959
|
-
{ method: "
|
|
10960
|
-
{ method: "
|
|
10975
|
+
// Language-scoped: generic class names `Pool`/`Connection`/`Client` substring-match
|
|
10976
|
+
// unrelated Java identifiers (cachedThreadPool, dbConnection). See issue #14.
|
|
10977
|
+
{ method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10978
|
+
{ method: "execute", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10979
|
+
{ method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10980
|
+
{ method: "execute", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10981
|
+
{ method: "sql_query", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10982
|
+
{ method: "raw_sql", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10983
|
+
{ method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10984
|
+
{ method: "query_row", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10985
|
+
{ method: "prepare", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10961
10986
|
// sqlx::query macro — use class-specific pattern
|
|
10962
10987
|
{ method: "query", class: "sqlx", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
10963
10988
|
// rusqlite specific
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
{ method: "
|
|
10989
|
+
// Language-scoped: classless `execute`/`prepare`/`query_map` collide with
|
|
10990
|
+
// Java util.concurrent (Executor.execute, ExecutorService) and other languages.
|
|
10991
|
+
{ method: "prepare", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10992
|
+
{ method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10993
|
+
{ method: "query_map", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10967
10994
|
// Rust Path Traversal
|
|
10968
10995
|
{ method: "open", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10969
10996
|
{ method: "create", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
{ method: "
|
|
10973
|
-
{ method: "
|
|
10974
|
-
{ method: "
|
|
10975
|
-
{ method: "
|
|
10976
|
-
{ method: "
|
|
10977
|
-
{ method: "
|
|
10978
|
-
{ method: "
|
|
10979
|
-
{ method: "
|
|
10980
|
-
{ method: "
|
|
10981
|
-
{ method: "
|
|
10997
|
+
// Language-scoped: classless std::fs helpers collide with Java/JS method names
|
|
10998
|
+
// (write, copy, rename, metadata, etc.) See issue #14.
|
|
10999
|
+
{ method: "read_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11000
|
+
{ method: "remove_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11001
|
+
{ method: "remove_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11002
|
+
{ method: "remove_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11003
|
+
{ method: "copy", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["rust"] },
|
|
11004
|
+
{ method: "rename", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["rust"] },
|
|
11005
|
+
{ method: "write", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11006
|
+
{ method: "read_to_string", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11007
|
+
{ method: "create_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11008
|
+
{ method: "create_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11009
|
+
{ method: "metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0], languages: ["rust"] },
|
|
11010
|
+
{ method: "symlink_metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0], languages: ["rust"] },
|
|
10982
11011
|
// Tokio async fs
|
|
10983
11012
|
{ method: "read_to_string", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10984
11013
|
{ method: "write", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -11256,9 +11285,9 @@ var PYTHON_TAINTED_PATTERNS = [
|
|
|
11256
11285
|
{ pattern: /\brequest\.query_params\b/, sourceType: "http_param" },
|
|
11257
11286
|
{ pattern: /\brequest\.path_params\b/, sourceType: "http_param" }
|
|
11258
11287
|
];
|
|
11259
|
-
function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy) {
|
|
11288
|
+
function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy, language) {
|
|
11260
11289
|
const sources = findSources(calls, types, config.sources);
|
|
11261
|
-
const sinks = findSinks(calls, config.sinks, typeHierarchy);
|
|
11290
|
+
const sinks = findSinks(calls, config.sinks, typeHierarchy, language);
|
|
11262
11291
|
const sanitizers = findSanitizers(calls, types, config.sanitizers);
|
|
11263
11292
|
return { sources, sinks, sanitizers };
|
|
11264
11293
|
}
|
|
@@ -11512,11 +11541,11 @@ function isParameterizedQueryCall(call, pattern) {
|
|
|
11512
11541
|
}
|
|
11513
11542
|
return false;
|
|
11514
11543
|
}
|
|
11515
|
-
function findSinks(calls, patterns, typeHierarchy) {
|
|
11544
|
+
function findSinks(calls, patterns, typeHierarchy, language) {
|
|
11516
11545
|
const sinkMap = /* @__PURE__ */ new Map();
|
|
11517
11546
|
for (const call of calls) {
|
|
11518
11547
|
for (const pattern of patterns) {
|
|
11519
|
-
if (matchesSinkPattern(call, pattern, typeHierarchy)) {
|
|
11548
|
+
if (matchesSinkPattern(call, pattern, typeHierarchy, language)) {
|
|
11520
11549
|
if (isParameterizedQueryCall(call, pattern)) {
|
|
11521
11550
|
continue;
|
|
11522
11551
|
}
|
|
@@ -11769,7 +11798,12 @@ function isKnownSafeReceiverForMethod(receiver, method, sinkType) {
|
|
|
11769
11798
|
}
|
|
11770
11799
|
return false;
|
|
11771
11800
|
}
|
|
11772
|
-
function matchesSinkPattern(call, pattern, typeHierarchy) {
|
|
11801
|
+
function matchesSinkPattern(call, pattern, typeHierarchy, language) {
|
|
11802
|
+
if (pattern.languages && pattern.languages.length > 0 && language !== void 0) {
|
|
11803
|
+
if (!pattern.languages.includes(language)) {
|
|
11804
|
+
return false;
|
|
11805
|
+
}
|
|
11806
|
+
}
|
|
11773
11807
|
const callMethodName = call.method_name;
|
|
11774
11808
|
const patternMethod = pattern.method;
|
|
11775
11809
|
let methodMatches = callMethodName === patternMethod;
|
|
@@ -11873,17 +11907,29 @@ function receiverMightBeClass(receiver, className) {
|
|
|
11873
11907
|
}
|
|
11874
11908
|
}
|
|
11875
11909
|
}
|
|
11876
|
-
|
|
11910
|
+
const ambiguousIdentifiers = /* @__PURE__ */ new Set([
|
|
11911
|
+
"executor",
|
|
11912
|
+
"pool",
|
|
11913
|
+
"connection",
|
|
11914
|
+
"manager",
|
|
11915
|
+
"handler",
|
|
11916
|
+
"controller",
|
|
11917
|
+
"task",
|
|
11918
|
+
"thread",
|
|
11919
|
+
"job"
|
|
11920
|
+
]);
|
|
11921
|
+
const isAmbiguous = ambiguousIdentifiers.has(lowerReceiver);
|
|
11922
|
+
if (!isAmbiguous && lowerReceiver.length >= 3 && lowerClass.includes(lowerReceiver)) {
|
|
11877
11923
|
if (lowerReceiver.length >= 5 || lowerReceiver.length / lowerClass.length >= 0.4) {
|
|
11878
11924
|
return true;
|
|
11879
11925
|
}
|
|
11880
11926
|
}
|
|
11881
|
-
if (lowerReceiver.length >= 2) {
|
|
11927
|
+
if (!isAmbiguous && lowerReceiver.length >= 2) {
|
|
11882
11928
|
if (lowerClass.startsWith(lowerReceiver) || lowerClass.endsWith(lowerReceiver)) {
|
|
11883
11929
|
return true;
|
|
11884
11930
|
}
|
|
11885
11931
|
}
|
|
11886
|
-
if (lowerReceiver.length >= 3) {
|
|
11932
|
+
if (!isAmbiguous && lowerReceiver.length >= 3) {
|
|
11887
11933
|
const words = className.replace(/([a-z])([A-Z])/g, "$1\0$2").toLowerCase().split("\0");
|
|
11888
11934
|
for (const word of words) {
|
|
11889
11935
|
if (word.startsWith(lowerReceiver) && lowerReceiver.length / word.length >= 0.4) {
|
|
@@ -13103,6 +13149,13 @@ var ANTI_SANITIZER_METHODS = /* @__PURE__ */ new Set([
|
|
|
13103
13149
|
"unescapeEcmaScript",
|
|
13104
13150
|
"unescapeJson",
|
|
13105
13151
|
"unescapeJava",
|
|
13152
|
+
// Apache Shiro WebUtils helpers (CVE-2023-34478, CVE-2023-46749 — issue #8).
|
|
13153
|
+
// These internally call URLDecoder.decode, so a value that passed a
|
|
13154
|
+
// string-level path sanitizer (e.g. Paths.normalize) becomes tainted again
|
|
13155
|
+
// after Shiro re-decodes %2e%2e → "..".
|
|
13156
|
+
"getPathWithinApplication",
|
|
13157
|
+
"getRequestUri",
|
|
13158
|
+
"decodeRequestString",
|
|
13106
13159
|
// General decoders
|
|
13107
13160
|
"unescape",
|
|
13108
13161
|
"decompress"
|
|
@@ -13138,8 +13191,15 @@ var PROPAGATOR_METHODS = /* @__PURE__ */ new Set([
|
|
|
13138
13191
|
"concat",
|
|
13139
13192
|
// String.concat(other)
|
|
13140
13193
|
// Object utilities
|
|
13141
|
-
"requireNonNull"
|
|
13194
|
+
"requireNonNull",
|
|
13142
13195
|
// Objects.requireNonNull(obj)
|
|
13196
|
+
// Apache Shiro WebUtils — propagate taint from string arg through the wrapper
|
|
13197
|
+
// back into the return value (e.g. `WebUtils.decodeRequestString(req, tainted)`).
|
|
13198
|
+
// Also covered by ANTI_SANITIZER_METHODS for sanitized-arg re-tainting and by
|
|
13199
|
+
// configs/sources/http_sources.yaml for the request-bound overloads. Issue #8.
|
|
13200
|
+
"getPathWithinApplication",
|
|
13201
|
+
"getRequestUri",
|
|
13202
|
+
"decodeRequestString"
|
|
13143
13203
|
]);
|
|
13144
13204
|
|
|
13145
13205
|
// src/analysis/constant-propagation/propagator.ts
|
package/dist/types/config.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Types for YAML configuration files (configs/sources/, configs/sinks/)
|
|
3
3
|
*/
|
|
4
|
-
import type { SarifLevel, Severity, SinkType, SourceType } from './index.js';
|
|
4
|
+
import type { SarifLevel, Severity, SinkType, SourceType, SupportedLanguage } from './index.js';
|
|
5
5
|
export interface SourceConfig {
|
|
6
6
|
sources: SourcePattern[];
|
|
7
7
|
}
|
|
@@ -30,6 +30,13 @@ export interface SinkPattern {
|
|
|
30
30
|
cwe: string;
|
|
31
31
|
severity: Severity;
|
|
32
32
|
arg_positions: number[];
|
|
33
|
+
/**
|
|
34
|
+
* Restrict the pattern to specific source languages. When omitted, the
|
|
35
|
+
* pattern matches calls regardless of language. Use this for sinks whose
|
|
36
|
+
* method name collides across language ecosystems (e.g. Python/Rust
|
|
37
|
+
* `cursor.execute()` vs Java `Executor.execute()`).
|
|
38
|
+
*/
|
|
39
|
+
languages?: SupportedLanguage[];
|
|
33
40
|
note?: string;
|
|
34
41
|
}
|
|
35
42
|
export interface SanitizerPattern {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMhG,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAE5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAIhB,UAAU,CAAC,EAAE,MAAM,CAAC;IAIpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IAGnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAMD;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;IACZ,0DAA0D;IAC1D,KAAK,EAAE,UAAU,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,EAAE,QAAQ,CAAC;IACnB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,cAAc,CAAC;IAChD;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circle-ir",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.30.0",
|
|
4
4
|
"description": "High-performance Static Application Security Testing (SAST) library for detecting security vulnerabilities through taint analysis",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|