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.
@@ -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
- { method: "execute", class: "Executor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
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
- { method: "execute", class: "Executor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
10186
- { method: "setCommandline", class: "Executor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
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
- { method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
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
- { method: "execSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
10810
- { method: "spawn", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
10811
- { method: "spawnSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
10812
- { method: "execFile", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
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
- { method: "query", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10826
- { method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10827
- { method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
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
- { method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0] },
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
- { method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
10886
- { method: "exec", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
10887
- { method: "compile", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0] },
10888
- { method: "__import__", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0] },
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
- { method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10897
- { method: "executemany", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10898
- { method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
10899
- { method: "extra", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0] },
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
- { method: "open", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
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
- { method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11018
- { method: "execute", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11019
- { method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11020
- { method: "execute", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11021
- { method: "sql_query", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11022
- { method: "raw_sql", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11023
- { method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11024
- { method: "query_row", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11025
- { method: "prepare", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
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
- { method: "prepare", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11030
- { method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
11031
- { method: "query_map", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
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
- { method: "read_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
11036
- { method: "remove_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
11037
- { method: "remove_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
11038
- { method: "remove_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
11039
- { method: "copy", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
11040
- { method: "rename", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
11041
- { method: "write", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
11042
- { method: "read_to_string", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
11043
- { method: "create_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
11044
- { method: "create_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
11045
- { method: "metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0] },
11046
- { method: "symlink_metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0] },
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
- if (lowerReceiver.length >= 3 && lowerClass.includes(lowerReceiver)) {
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