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
|
@@ -9742,6 +9742,13 @@ var DEFAULT_SOURCES = [
|
|
|
9742
9742
|
{ method: "getContextPath", class: "HttpServletRequest", type: "http_path", severity: "medium", return_tainted: true },
|
|
9743
9743
|
{ method: "getRemoteHost", class: "HttpServletRequest", type: "http_header", severity: "medium", return_tainted: true },
|
|
9744
9744
|
{ method: "getRemoteAddr", class: "HttpServletRequest", type: "http_header", severity: "medium", return_tainted: true },
|
|
9745
|
+
// Apache Shiro WebUtils helpers — return URL-decoded request data. The internal
|
|
9746
|
+
// decodeRequestString → URLDecoder.decode chain can re-introduce ../ from
|
|
9747
|
+
// %2e%2e payloads that bypassed auth-time normalization. CVE-2023-34478,
|
|
9748
|
+
// CVE-2023-46749 (issue #8).
|
|
9749
|
+
{ method: "getPathWithinApplication", class: "WebUtils", type: "http_path", severity: "high", return_tainted: true },
|
|
9750
|
+
{ method: "getRequestUri", class: "WebUtils", type: "http_path", severity: "high", return_tainted: true },
|
|
9751
|
+
{ method: "decodeRequestString", class: "WebUtils", type: "http_path", severity: "high", return_tainted: true },
|
|
9745
9752
|
// Additional HTTP request methods that can be attacker-controlled
|
|
9746
9753
|
{ method: "getProtocol", class: "HttpServletRequest", type: "http_header", severity: "medium", return_tainted: true },
|
|
9747
9754
|
{ method: "getScheme", class: "HttpServletRequest", type: "http_header", severity: "medium", return_tainted: true },
|
|
@@ -10114,7 +10121,9 @@ var DEFAULT_SINKS = [
|
|
|
10114
10121
|
{ method: "ProcessBuilder", class: "constructor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10115
10122
|
{ method: "command", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10116
10123
|
// Commons Exec
|
|
10117
|
-
|
|
10124
|
+
// Note: bare class 'Executor' removed — it collided with java.util.concurrent.Executor
|
|
10125
|
+
// (Executor.execute(Runnable) is not command injection). Apache Commons Exec users
|
|
10126
|
+
// typically declare DefaultExecutor explicitly, so we match that instead. See issue #14.
|
|
10118
10127
|
{ method: "execute", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10119
10128
|
{ method: "CommandLine", class: "constructor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10120
10129
|
{ method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
@@ -10182,8 +10191,8 @@ var DEFAULT_SINKS = [
|
|
|
10182
10191
|
{ method: "popen", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10183
10192
|
{ method: "system", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10184
10193
|
// Apache Commons Exec
|
|
10185
|
-
|
|
10186
|
-
{ method: "setCommandline", class: "
|
|
10194
|
+
// Note: bare class 'Executor' removed (see comment above) — DefaultExecutor matched explicitly.
|
|
10195
|
+
{ method: "setCommandline", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10187
10196
|
{ method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10188
10197
|
{ method: "addArgument", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10189
10198
|
// Process-related utilities
|
|
@@ -10192,7 +10201,10 @@ var DEFAULT_SINKS = [
|
|
|
10192
10201
|
{ method: "redirectOutput", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "medium", arg_positions: [0] },
|
|
10193
10202
|
{ method: "redirectInput", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "medium", arg_positions: [0] },
|
|
10194
10203
|
// Path Traversal (CWE-22)
|
|
10195
|
-
|
|
10204
|
+
// File: covers both File(String pathname) and File(parent, child). The 2-arg
|
|
10205
|
+
// overload's child argument carries CVE-2018-8041 (Camel mail Content-Disposition
|
|
10206
|
+
// filename written to disk).
|
|
10207
|
+
{ method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
|
|
10196
10208
|
{ method: "FileInputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10197
10209
|
{ method: "FileOutputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10198
10210
|
{ method: "FileReader", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -10805,11 +10817,14 @@ var DEFAULT_SINKS = [
|
|
|
10805
10817
|
{ method: "spawn", class: "child_process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10806
10818
|
{ method: "spawnSync", class: "child_process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10807
10819
|
// Also match without receiver (destructured imports: const { exec } = require('child_process'))
|
|
10820
|
+
// `exec` is intentionally classless: catches Node.js child_process.exec AND
|
|
10821
|
+
// Java Runtime.exec (via `r.exec()` where heuristic can't resolve r → Runtime).
|
|
10808
10822
|
{ method: "exec", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
|
|
10809
|
-
|
|
10810
|
-
{ method: "
|
|
10811
|
-
{ method: "
|
|
10812
|
-
{ method: "
|
|
10823
|
+
// `execSync`/`spawn`/`spawnSync`/`execFile` are Node-specific — language-scope them.
|
|
10824
|
+
{ method: "execSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10825
|
+
{ method: "spawn", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10826
|
+
{ method: "spawnSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10827
|
+
{ method: "execFile", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10813
10828
|
// Node.js File System (path traversal)
|
|
10814
10829
|
{ method: "readFile", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10815
10830
|
{ method: "readFileSync", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
@@ -10822,12 +10837,15 @@ var DEFAULT_SINKS = [
|
|
|
10822
10837
|
{ method: "createReadStream", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10823
10838
|
{ method: "createWriteStream", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10824
10839
|
// Node.js SQL (mysql, pg, sqlite, etc.)
|
|
10825
|
-
|
|
10826
|
-
|
|
10827
|
-
{ method: "query", class: "
|
|
10840
|
+
// Language-scoped: generic class names `Pool`/`Connection`/`Client` substring-match
|
|
10841
|
+
// unrelated Java identifiers like `cachedThreadPool`, `dbConnection`. See issue #14.
|
|
10842
|
+
{ method: "query", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10843
|
+
{ method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10844
|
+
{ method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10828
10845
|
// Note: classless { method: 'query' } removed — too many FPs (UriComponentsBuilder.query(), etc.)
|
|
10829
10846
|
// SQL query calls are covered by class-specific patterns above (Connection, Pool, Client, JdbcTemplate)
|
|
10830
|
-
|
|
10847
|
+
// Note: `raw` is shared with Python (Django ORM) — scoped to JS+TS to avoid leaking.
|
|
10848
|
+
{ method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10831
10849
|
// Browser DOM XSS sinks
|
|
10832
10850
|
{ method: "setAttribute", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [1] },
|
|
10833
10851
|
// Express.js XSS (response methods)
|
|
@@ -10837,7 +10855,7 @@ var DEFAULT_SINKS = [
|
|
|
10837
10855
|
{ method: "html", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10838
10856
|
{ method: "render", class: "Response", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [1] },
|
|
10839
10857
|
// Node.js Code Injection (eval, vm, etc.)
|
|
10840
|
-
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10858
|
+
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10841
10859
|
{ method: "Function", class: "constructor", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10842
10860
|
{ method: "runInContext", class: "vm", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10843
10861
|
{ method: "runInNewContext", class: "vm", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
@@ -10853,7 +10871,7 @@ var DEFAULT_SINKS = [
|
|
|
10853
10871
|
{ method: "get", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10854
10872
|
{ method: "post", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10855
10873
|
{ method: "request", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10856
|
-
{ method: "fetch", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10874
|
+
{ method: "fetch", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10857
10875
|
{ method: "request", class: "http", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10858
10876
|
{ method: "get", class: "http", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10859
10877
|
{ method: "request", class: "https", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
@@ -10882,10 +10900,12 @@ var DEFAULT_SINKS = [
|
|
|
10882
10900
|
{ method: "check_call", class: "subprocess", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10883
10901
|
{ method: "Popen", class: "subprocess", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10884
10902
|
// Python Code Injection
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
{ method: "
|
|
10888
|
-
{ method: "
|
|
10903
|
+
// Language-scoped: classless `exec`/`eval`/`compile` collide with Java/JS builtins
|
|
10904
|
+
// and Java util.concurrent (e.g. Executor.execute / future.compile).
|
|
10905
|
+
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10906
|
+
{ method: "exec", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10907
|
+
{ method: "compile", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10908
|
+
{ method: "__import__", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10889
10909
|
// Python Deserialization
|
|
10890
10910
|
{ method: "loads", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10891
10911
|
{ method: "load", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
@@ -10893,36 +10913,39 @@ var DEFAULT_SINKS = [
|
|
|
10893
10913
|
{ method: "load", class: "yaml", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10894
10914
|
{ method: "loads", class: "yaml", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10895
10915
|
// Python SQL Injection
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
{ method: "
|
|
10899
|
-
{ method: "
|
|
10916
|
+
// Language-scoped: classless `execute`/`raw` collide with Java util.concurrent
|
|
10917
|
+
// (Executor.execute, ThreadPool.execute) and other languages. See issue #14.
|
|
10918
|
+
{ method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10919
|
+
{ method: "executemany", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10920
|
+
{ method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10921
|
+
{ method: "extra", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10900
10922
|
// Python Path Traversal
|
|
10901
|
-
|
|
10923
|
+
// Language-scoped: classless `open` collides with Java I/O / JS DOM.
|
|
10924
|
+
{ method: "open", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10902
10925
|
{ method: "remove", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10903
10926
|
{ method: "unlink", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10904
10927
|
{ method: "rmdir", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10905
10928
|
{ method: "rmtree", class: "shutil", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10906
|
-
{ method: "send_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10929
|
+
{ method: "send_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10907
10930
|
// Python XSS / SSTI
|
|
10908
|
-
{ method: "render_template_string", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10909
|
-
{ method: "Markup", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10910
|
-
{ method: "mark_safe", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10931
|
+
{ method: "render_template_string", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10932
|
+
{ method: "Markup", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10933
|
+
{ method: "mark_safe", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10911
10934
|
// Python SSRF
|
|
10912
10935
|
{ method: "get", class: "requests", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10913
10936
|
{ method: "post", class: "requests", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10914
10937
|
{ method: "urlopen", class: "urllib.request", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10915
10938
|
// Python Open Redirect
|
|
10916
|
-
{ method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0] },
|
|
10939
|
+
{ method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["python"] },
|
|
10917
10940
|
// Python XPath Injection
|
|
10918
|
-
{ method: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10941
|
+
{ method: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10919
10942
|
{ method: "find", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10920
10943
|
{ method: "findall", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10921
10944
|
{ method: "iterfind", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10922
10945
|
{ method: "XPath", class: "lxml", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10923
10946
|
// elementpath library (XPath 2.0/3.0)
|
|
10924
10947
|
{ method: "select", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [1] },
|
|
10925
|
-
{ method: "select", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10948
|
+
{ method: "select", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10926
10949
|
{ method: "iter_select", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [1] },
|
|
10927
10950
|
{ method: "Selector", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10928
10951
|
// Python XXE
|
|
@@ -11014,36 +11037,42 @@ var DEFAULT_SINKS = [
|
|
|
11014
11037
|
{ method: "arg", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11015
11038
|
{ method: "args", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11016
11039
|
// Rust SQL Injection (sqlx, diesel, rusqlite, tokio-postgres)
|
|
11017
|
-
|
|
11018
|
-
|
|
11019
|
-
{ method: "query", class: "
|
|
11020
|
-
{ method: "execute", class: "
|
|
11021
|
-
{ method: "
|
|
11022
|
-
{ method: "
|
|
11023
|
-
{ method: "
|
|
11024
|
-
{ method: "
|
|
11025
|
-
{ method: "
|
|
11040
|
+
// Language-scoped: generic class names `Pool`/`Connection`/`Client` substring-match
|
|
11041
|
+
// unrelated Java identifiers (cachedThreadPool, dbConnection). See issue #14.
|
|
11042
|
+
{ method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11043
|
+
{ method: "execute", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11044
|
+
{ method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11045
|
+
{ method: "execute", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11046
|
+
{ method: "sql_query", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11047
|
+
{ method: "raw_sql", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11048
|
+
{ method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11049
|
+
{ method: "query_row", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11050
|
+
{ method: "prepare", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11026
11051
|
// sqlx::query macro — use class-specific pattern
|
|
11027
11052
|
{ method: "query", class: "sqlx", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
11028
11053
|
// rusqlite specific
|
|
11029
|
-
|
|
11030
|
-
|
|
11031
|
-
{ method: "
|
|
11054
|
+
// Language-scoped: classless `execute`/`prepare`/`query_map` collide with
|
|
11055
|
+
// Java util.concurrent (Executor.execute, ExecutorService) and other languages.
|
|
11056
|
+
{ method: "prepare", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11057
|
+
{ method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11058
|
+
{ method: "query_map", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11032
11059
|
// Rust Path Traversal
|
|
11033
11060
|
{ method: "open", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11034
11061
|
{ method: "create", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11035
|
-
|
|
11036
|
-
|
|
11037
|
-
{ method: "
|
|
11038
|
-
{ method: "
|
|
11039
|
-
{ method: "
|
|
11040
|
-
{ method: "
|
|
11041
|
-
{ method: "
|
|
11042
|
-
{ method: "
|
|
11043
|
-
{ method: "
|
|
11044
|
-
{ method: "
|
|
11045
|
-
{ method: "
|
|
11046
|
-
{ method: "
|
|
11062
|
+
// Language-scoped: classless std::fs helpers collide with Java/JS method names
|
|
11063
|
+
// (write, copy, rename, metadata, etc.) See issue #14.
|
|
11064
|
+
{ method: "read_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11065
|
+
{ method: "remove_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11066
|
+
{ method: "remove_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11067
|
+
{ method: "remove_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
11068
|
+
{ method: "copy", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["rust"] },
|
|
11069
|
+
{ method: "rename", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["rust"] },
|
|
11070
|
+
{ method: "write", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11071
|
+
{ method: "read_to_string", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11072
|
+
{ method: "create_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11073
|
+
{ method: "create_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11074
|
+
{ method: "metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0], languages: ["rust"] },
|
|
11075
|
+
{ method: "symlink_metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0], languages: ["rust"] },
|
|
11047
11076
|
// Tokio async fs
|
|
11048
11077
|
{ method: "read_to_string", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11049
11078
|
{ method: "write", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -11321,9 +11350,9 @@ var PYTHON_TAINTED_PATTERNS = [
|
|
|
11321
11350
|
{ pattern: /\brequest\.query_params\b/, sourceType: "http_param" },
|
|
11322
11351
|
{ pattern: /\brequest\.path_params\b/, sourceType: "http_param" }
|
|
11323
11352
|
];
|
|
11324
|
-
function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy) {
|
|
11353
|
+
function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy, language) {
|
|
11325
11354
|
const sources = findSources(calls, types, config.sources);
|
|
11326
|
-
const sinks = findSinks(calls, config.sinks, typeHierarchy);
|
|
11355
|
+
const sinks = findSinks(calls, config.sinks, typeHierarchy, language);
|
|
11327
11356
|
const sanitizers = findSanitizers(calls, types, config.sanitizers);
|
|
11328
11357
|
return { sources, sinks, sanitizers };
|
|
11329
11358
|
}
|
|
@@ -11577,11 +11606,11 @@ function isParameterizedQueryCall(call, pattern) {
|
|
|
11577
11606
|
}
|
|
11578
11607
|
return false;
|
|
11579
11608
|
}
|
|
11580
|
-
function findSinks(calls, patterns, typeHierarchy) {
|
|
11609
|
+
function findSinks(calls, patterns, typeHierarchy, language) {
|
|
11581
11610
|
const sinkMap = /* @__PURE__ */ new Map();
|
|
11582
11611
|
for (const call of calls) {
|
|
11583
11612
|
for (const pattern of patterns) {
|
|
11584
|
-
if (matchesSinkPattern(call, pattern, typeHierarchy)) {
|
|
11613
|
+
if (matchesSinkPattern(call, pattern, typeHierarchy, language)) {
|
|
11585
11614
|
if (isParameterizedQueryCall(call, pattern)) {
|
|
11586
11615
|
continue;
|
|
11587
11616
|
}
|
|
@@ -11834,7 +11863,12 @@ function isKnownSafeReceiverForMethod(receiver, method, sinkType) {
|
|
|
11834
11863
|
}
|
|
11835
11864
|
return false;
|
|
11836
11865
|
}
|
|
11837
|
-
function matchesSinkPattern(call, pattern, typeHierarchy) {
|
|
11866
|
+
function matchesSinkPattern(call, pattern, typeHierarchy, language) {
|
|
11867
|
+
if (pattern.languages && pattern.languages.length > 0 && language !== void 0) {
|
|
11868
|
+
if (!pattern.languages.includes(language)) {
|
|
11869
|
+
return false;
|
|
11870
|
+
}
|
|
11871
|
+
}
|
|
11838
11872
|
const callMethodName = call.method_name;
|
|
11839
11873
|
const patternMethod = pattern.method;
|
|
11840
11874
|
let methodMatches = callMethodName === patternMethod;
|
|
@@ -11938,17 +11972,29 @@ function receiverMightBeClass(receiver, className) {
|
|
|
11938
11972
|
}
|
|
11939
11973
|
}
|
|
11940
11974
|
}
|
|
11941
|
-
|
|
11975
|
+
const ambiguousIdentifiers = /* @__PURE__ */ new Set([
|
|
11976
|
+
"executor",
|
|
11977
|
+
"pool",
|
|
11978
|
+
"connection",
|
|
11979
|
+
"manager",
|
|
11980
|
+
"handler",
|
|
11981
|
+
"controller",
|
|
11982
|
+
"task",
|
|
11983
|
+
"thread",
|
|
11984
|
+
"job"
|
|
11985
|
+
]);
|
|
11986
|
+
const isAmbiguous = ambiguousIdentifiers.has(lowerReceiver);
|
|
11987
|
+
if (!isAmbiguous && lowerReceiver.length >= 3 && lowerClass.includes(lowerReceiver)) {
|
|
11942
11988
|
if (lowerReceiver.length >= 5 || lowerReceiver.length / lowerClass.length >= 0.4) {
|
|
11943
11989
|
return true;
|
|
11944
11990
|
}
|
|
11945
11991
|
}
|
|
11946
|
-
if (lowerReceiver.length >= 2) {
|
|
11992
|
+
if (!isAmbiguous && lowerReceiver.length >= 2) {
|
|
11947
11993
|
if (lowerClass.startsWith(lowerReceiver) || lowerClass.endsWith(lowerReceiver)) {
|
|
11948
11994
|
return true;
|
|
11949
11995
|
}
|
|
11950
11996
|
}
|
|
11951
|
-
if (lowerReceiver.length >= 3) {
|
|
11997
|
+
if (!isAmbiguous && lowerReceiver.length >= 3) {
|
|
11952
11998
|
const words = className.replace(/([a-z])([A-Z])/g, "$1\0$2").toLowerCase().split("\0");
|
|
11953
11999
|
for (const word of words) {
|
|
11954
12000
|
if (word.startsWith(lowerReceiver) && lowerReceiver.length / word.length >= 0.4) {
|
|
@@ -13168,6 +13214,13 @@ var ANTI_SANITIZER_METHODS = /* @__PURE__ */ new Set([
|
|
|
13168
13214
|
"unescapeEcmaScript",
|
|
13169
13215
|
"unescapeJson",
|
|
13170
13216
|
"unescapeJava",
|
|
13217
|
+
// Apache Shiro WebUtils helpers (CVE-2023-34478, CVE-2023-46749 — issue #8).
|
|
13218
|
+
// These internally call URLDecoder.decode, so a value that passed a
|
|
13219
|
+
// string-level path sanitizer (e.g. Paths.normalize) becomes tainted again
|
|
13220
|
+
// after Shiro re-decodes %2e%2e → "..".
|
|
13221
|
+
"getPathWithinApplication",
|
|
13222
|
+
"getRequestUri",
|
|
13223
|
+
"decodeRequestString",
|
|
13171
13224
|
// General decoders
|
|
13172
13225
|
"unescape",
|
|
13173
13226
|
"decompress"
|
|
@@ -13203,8 +13256,15 @@ var PROPAGATOR_METHODS = /* @__PURE__ */ new Set([
|
|
|
13203
13256
|
"concat",
|
|
13204
13257
|
// String.concat(other)
|
|
13205
13258
|
// Object utilities
|
|
13206
|
-
"requireNonNull"
|
|
13259
|
+
"requireNonNull",
|
|
13207
13260
|
// Objects.requireNonNull(obj)
|
|
13261
|
+
// Apache Shiro WebUtils — propagate taint from string arg through the wrapper
|
|
13262
|
+
// back into the return value (e.g. `WebUtils.decodeRequestString(req, tainted)`).
|
|
13263
|
+
// Also covered by ANTI_SANITIZER_METHODS for sanitized-arg re-tainting and by
|
|
13264
|
+
// configs/sources/http_sources.yaml for the request-bound overloads. Issue #8.
|
|
13265
|
+
"getPathWithinApplication",
|
|
13266
|
+
"getRequestUri",
|
|
13267
|
+
"decodeRequestString"
|
|
13208
13268
|
]);
|
|
13209
13269
|
|
|
13210
13270
|
// src/analysis/constant-propagation/propagator.ts
|