circle-ir 3.28.0 → 3.29.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/dist/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +76 -54
- package/dist/analysis/config-loader.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 +103 -64
- package/dist/core/circle-ir-core.cjs +101 -62
- package/dist/core/circle-ir-core.js +101 -62
- package/dist/types/config.d.ts +8 -1
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -10049,7 +10049,9 @@ var DEFAULT_SINKS = [
|
|
|
10049
10049
|
{ method: "ProcessBuilder", class: "constructor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10050
10050
|
{ method: "command", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10051
10051
|
// Commons Exec
|
|
10052
|
-
|
|
10052
|
+
// Note: bare class 'Executor' removed — it collided with java.util.concurrent.Executor
|
|
10053
|
+
// (Executor.execute(Runnable) is not command injection). Apache Commons Exec users
|
|
10054
|
+
// typically declare DefaultExecutor explicitly, so we match that instead. See issue #14.
|
|
10053
10055
|
{ method: "execute", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10054
10056
|
{ method: "CommandLine", class: "constructor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10055
10057
|
{ method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
@@ -10117,8 +10119,8 @@ var DEFAULT_SINKS = [
|
|
|
10117
10119
|
{ method: "popen", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10118
10120
|
{ method: "system", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10119
10121
|
// Apache Commons Exec
|
|
10120
|
-
|
|
10121
|
-
{ method: "setCommandline", class: "
|
|
10122
|
+
// Note: bare class 'Executor' removed (see comment above) — DefaultExecutor matched explicitly.
|
|
10123
|
+
{ method: "setCommandline", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10122
10124
|
{ method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10123
10125
|
{ method: "addArgument", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10124
10126
|
// Process-related utilities
|
|
@@ -10127,7 +10129,10 @@ var DEFAULT_SINKS = [
|
|
|
10127
10129
|
{ method: "redirectOutput", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "medium", arg_positions: [0] },
|
|
10128
10130
|
{ method: "redirectInput", class: "ProcessBuilder", type: "command_injection", cwe: "CWE-78", severity: "medium", arg_positions: [0] },
|
|
10129
10131
|
// Path Traversal (CWE-22)
|
|
10130
|
-
|
|
10132
|
+
// File: covers both File(String pathname) and File(parent, child). The 2-arg
|
|
10133
|
+
// overload's child argument carries CVE-2018-8041 (Camel mail Content-Disposition
|
|
10134
|
+
// filename written to disk).
|
|
10135
|
+
{ method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
|
|
10131
10136
|
{ method: "FileInputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10132
10137
|
{ method: "FileOutputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10133
10138
|
{ method: "FileReader", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -10740,11 +10745,14 @@ var DEFAULT_SINKS = [
|
|
|
10740
10745
|
{ method: "spawn", class: "child_process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10741
10746
|
{ method: "spawnSync", class: "child_process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10742
10747
|
// Also match without receiver (destructured imports: const { exec } = require('child_process'))
|
|
10748
|
+
// `exec` is intentionally classless: catches Node.js child_process.exec AND
|
|
10749
|
+
// Java Runtime.exec (via `r.exec()` where heuristic can't resolve r → Runtime).
|
|
10743
10750
|
{ method: "exec", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0] },
|
|
10744
|
-
|
|
10745
|
-
{ method: "
|
|
10746
|
-
{ method: "
|
|
10747
|
-
{ method: "
|
|
10751
|
+
// `execSync`/`spawn`/`spawnSync`/`execFile` are Node-specific — language-scope them.
|
|
10752
|
+
{ method: "execSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10753
|
+
{ method: "spawn", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10754
|
+
{ method: "spawnSync", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10755
|
+
{ method: "execFile", type: "command_injection", cwe: "CWE-78", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10748
10756
|
// Node.js File System (path traversal)
|
|
10749
10757
|
{ method: "readFile", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10750
10758
|
{ method: "readFileSync", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
@@ -10757,12 +10765,15 @@ var DEFAULT_SINKS = [
|
|
|
10757
10765
|
{ method: "createReadStream", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10758
10766
|
{ method: "createWriteStream", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0] },
|
|
10759
10767
|
// Node.js SQL (mysql, pg, sqlite, etc.)
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
{ method: "query", class: "
|
|
10768
|
+
// Language-scoped: generic class names `Pool`/`Connection`/`Client` substring-match
|
|
10769
|
+
// unrelated Java identifiers like `cachedThreadPool`, `dbConnection`. See issue #14.
|
|
10770
|
+
{ method: "query", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10771
|
+
{ method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10772
|
+
{ method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10763
10773
|
// Note: classless { method: 'query' } removed — too many FPs (UriComponentsBuilder.query(), etc.)
|
|
10764
10774
|
// SQL query calls are covered by class-specific patterns above (Connection, Pool, Client, JdbcTemplate)
|
|
10765
|
-
|
|
10775
|
+
// Note: `raw` is shared with Python (Django ORM) — scoped to JS+TS to avoid leaking.
|
|
10776
|
+
{ method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10766
10777
|
// Browser DOM XSS sinks
|
|
10767
10778
|
{ method: "setAttribute", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [1] },
|
|
10768
10779
|
// Express.js XSS (response methods)
|
|
@@ -10772,7 +10783,7 @@ var DEFAULT_SINKS = [
|
|
|
10772
10783
|
{ method: "html", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10773
10784
|
{ method: "render", class: "Response", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [1] },
|
|
10774
10785
|
// Node.js Code Injection (eval, vm, etc.)
|
|
10775
|
-
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10786
|
+
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10776
10787
|
{ method: "Function", class: "constructor", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10777
10788
|
{ method: "runInContext", class: "vm", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
10778
10789
|
{ method: "runInNewContext", class: "vm", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
@@ -10788,7 +10799,7 @@ var DEFAULT_SINKS = [
|
|
|
10788
10799
|
{ method: "get", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10789
10800
|
{ method: "post", class: "axios", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10790
10801
|
{ 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] },
|
|
10802
|
+
{ method: "fetch", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10792
10803
|
{ method: "request", class: "http", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10793
10804
|
{ method: "get", class: "http", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10794
10805
|
{ method: "request", class: "https", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
@@ -10817,10 +10828,12 @@ var DEFAULT_SINKS = [
|
|
|
10817
10828
|
{ method: "check_call", class: "subprocess", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10818
10829
|
{ method: "Popen", class: "subprocess", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10819
10830
|
// Python Code Injection
|
|
10820
|
-
|
|
10821
|
-
|
|
10822
|
-
{ method: "
|
|
10823
|
-
{ method: "
|
|
10831
|
+
// Language-scoped: classless `exec`/`eval`/`compile` collide with Java/JS builtins
|
|
10832
|
+
// and Java util.concurrent (e.g. Executor.execute / future.compile).
|
|
10833
|
+
{ method: "eval", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10834
|
+
{ method: "exec", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10835
|
+
{ method: "compile", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10836
|
+
{ method: "__import__", type: "code_injection", cwe: "CWE-94", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10824
10837
|
// Python Deserialization
|
|
10825
10838
|
{ method: "loads", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10826
10839
|
{ method: "load", class: "pickle", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
@@ -10828,36 +10841,39 @@ var DEFAULT_SINKS = [
|
|
|
10828
10841
|
{ method: "load", class: "yaml", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10829
10842
|
{ method: "loads", class: "yaml", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
10830
10843
|
// Python SQL Injection
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
{ method: "
|
|
10834
|
-
{ method: "
|
|
10844
|
+
// Language-scoped: classless `execute`/`raw` collide with Java util.concurrent
|
|
10845
|
+
// (Executor.execute, ThreadPool.execute) and other languages. See issue #14.
|
|
10846
|
+
{ method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10847
|
+
{ method: "executemany", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10848
|
+
{ method: "raw", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["python"] },
|
|
10849
|
+
{ method: "extra", type: "sql_injection", cwe: "CWE-89", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10835
10850
|
// Python Path Traversal
|
|
10836
|
-
|
|
10851
|
+
// Language-scoped: classless `open` collides with Java I/O / JS DOM.
|
|
10852
|
+
{ method: "open", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10837
10853
|
{ method: "remove", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10838
10854
|
{ method: "unlink", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10839
10855
|
{ method: "rmdir", class: "os", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10840
10856
|
{ 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] },
|
|
10857
|
+
{ method: "send_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10842
10858
|
// 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] },
|
|
10859
|
+
{ method: "render_template_string", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10860
|
+
{ method: "Markup", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10861
|
+
{ method: "mark_safe", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10846
10862
|
// Python SSRF
|
|
10847
10863
|
{ method: "get", class: "requests", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10848
10864
|
{ method: "post", class: "requests", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10849
10865
|
{ method: "urlopen", class: "urllib.request", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
10850
10866
|
// Python Open Redirect
|
|
10851
|
-
{ method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0] },
|
|
10867
|
+
{ method: "redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["python"] },
|
|
10852
10868
|
// Python XPath Injection
|
|
10853
|
-
{ method: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10869
|
+
{ method: "xpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10854
10870
|
{ method: "find", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10855
10871
|
{ method: "findall", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10856
10872
|
{ method: "iterfind", class: "etree", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10857
10873
|
{ method: "XPath", class: "lxml", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10858
10874
|
// elementpath library (XPath 2.0/3.0)
|
|
10859
10875
|
{ 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] },
|
|
10876
|
+
{ method: "select", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["python"] },
|
|
10861
10877
|
{ method: "iter_select", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [1] },
|
|
10862
10878
|
{ method: "Selector", class: "elementpath", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0] },
|
|
10863
10879
|
// Python XXE
|
|
@@ -10949,36 +10965,42 @@ var DEFAULT_SINKS = [
|
|
|
10949
10965
|
{ method: "arg", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10950
10966
|
{ method: "args", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
10951
10967
|
// 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: "
|
|
10968
|
+
// Language-scoped: generic class names `Pool`/`Connection`/`Client` substring-match
|
|
10969
|
+
// unrelated Java identifiers (cachedThreadPool, dbConnection). See issue #14.
|
|
10970
|
+
{ method: "query", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10971
|
+
{ method: "execute", class: "Client", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10972
|
+
{ method: "query", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10973
|
+
{ method: "execute", class: "Pool", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10974
|
+
{ method: "sql_query", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10975
|
+
{ method: "raw_sql", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10976
|
+
{ method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10977
|
+
{ method: "query_row", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10978
|
+
{ method: "prepare", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10961
10979
|
// sqlx::query macro — use class-specific pattern
|
|
10962
10980
|
{ method: "query", class: "sqlx", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
10963
10981
|
// rusqlite specific
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
{ method: "
|
|
10982
|
+
// Language-scoped: classless `execute`/`prepare`/`query_map` collide with
|
|
10983
|
+
// Java util.concurrent (Executor.execute, ExecutorService) and other languages.
|
|
10984
|
+
{ method: "prepare", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10985
|
+
{ method: "execute", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10986
|
+
{ method: "query_map", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10967
10987
|
// Rust Path Traversal
|
|
10968
10988
|
{ method: "open", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10969
10989
|
{ 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: "
|
|
10990
|
+
// Language-scoped: classless std::fs helpers collide with Java/JS method names
|
|
10991
|
+
// (write, copy, rename, metadata, etc.) See issue #14.
|
|
10992
|
+
{ method: "read_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
10993
|
+
{ method: "remove_file", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
10994
|
+
{ method: "remove_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
10995
|
+
{ method: "remove_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "critical", arg_positions: [0], languages: ["rust"] },
|
|
10996
|
+
{ method: "copy", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["rust"] },
|
|
10997
|
+
{ method: "rename", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["rust"] },
|
|
10998
|
+
{ method: "write", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
10999
|
+
{ method: "read_to_string", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11000
|
+
{ method: "create_dir", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11001
|
+
{ method: "create_dir_all", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["rust"] },
|
|
11002
|
+
{ method: "metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0], languages: ["rust"] },
|
|
11003
|
+
{ method: "symlink_metadata", type: "path_traversal", cwe: "CWE-22", severity: "medium", arg_positions: [0], languages: ["rust"] },
|
|
10982
11004
|
// Tokio async fs
|
|
10983
11005
|
{ method: "read_to_string", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
10984
11006
|
{ method: "write", class: "fs", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -11256,9 +11278,9 @@ var PYTHON_TAINTED_PATTERNS = [
|
|
|
11256
11278
|
{ pattern: /\brequest\.query_params\b/, sourceType: "http_param" },
|
|
11257
11279
|
{ pattern: /\brequest\.path_params\b/, sourceType: "http_param" }
|
|
11258
11280
|
];
|
|
11259
|
-
function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy) {
|
|
11281
|
+
function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy, language) {
|
|
11260
11282
|
const sources = findSources(calls, types, config.sources);
|
|
11261
|
-
const sinks = findSinks(calls, config.sinks, typeHierarchy);
|
|
11283
|
+
const sinks = findSinks(calls, config.sinks, typeHierarchy, language);
|
|
11262
11284
|
const sanitizers = findSanitizers(calls, types, config.sanitizers);
|
|
11263
11285
|
return { sources, sinks, sanitizers };
|
|
11264
11286
|
}
|
|
@@ -11512,11 +11534,11 @@ function isParameterizedQueryCall(call, pattern) {
|
|
|
11512
11534
|
}
|
|
11513
11535
|
return false;
|
|
11514
11536
|
}
|
|
11515
|
-
function findSinks(calls, patterns, typeHierarchy) {
|
|
11537
|
+
function findSinks(calls, patterns, typeHierarchy, language) {
|
|
11516
11538
|
const sinkMap = /* @__PURE__ */ new Map();
|
|
11517
11539
|
for (const call of calls) {
|
|
11518
11540
|
for (const pattern of patterns) {
|
|
11519
|
-
if (matchesSinkPattern(call, pattern, typeHierarchy)) {
|
|
11541
|
+
if (matchesSinkPattern(call, pattern, typeHierarchy, language)) {
|
|
11520
11542
|
if (isParameterizedQueryCall(call, pattern)) {
|
|
11521
11543
|
continue;
|
|
11522
11544
|
}
|
|
@@ -11769,7 +11791,12 @@ function isKnownSafeReceiverForMethod(receiver, method, sinkType) {
|
|
|
11769
11791
|
}
|
|
11770
11792
|
return false;
|
|
11771
11793
|
}
|
|
11772
|
-
function matchesSinkPattern(call, pattern, typeHierarchy) {
|
|
11794
|
+
function matchesSinkPattern(call, pattern, typeHierarchy, language) {
|
|
11795
|
+
if (pattern.languages && pattern.languages.length > 0 && language !== void 0) {
|
|
11796
|
+
if (!pattern.languages.includes(language)) {
|
|
11797
|
+
return false;
|
|
11798
|
+
}
|
|
11799
|
+
}
|
|
11773
11800
|
const callMethodName = call.method_name;
|
|
11774
11801
|
const patternMethod = pattern.method;
|
|
11775
11802
|
let methodMatches = callMethodName === patternMethod;
|
|
@@ -11873,17 +11900,29 @@ function receiverMightBeClass(receiver, className) {
|
|
|
11873
11900
|
}
|
|
11874
11901
|
}
|
|
11875
11902
|
}
|
|
11876
|
-
|
|
11903
|
+
const ambiguousIdentifiers = /* @__PURE__ */ new Set([
|
|
11904
|
+
"executor",
|
|
11905
|
+
"pool",
|
|
11906
|
+
"connection",
|
|
11907
|
+
"manager",
|
|
11908
|
+
"handler",
|
|
11909
|
+
"controller",
|
|
11910
|
+
"task",
|
|
11911
|
+
"thread",
|
|
11912
|
+
"job"
|
|
11913
|
+
]);
|
|
11914
|
+
const isAmbiguous = ambiguousIdentifiers.has(lowerReceiver);
|
|
11915
|
+
if (!isAmbiguous && lowerReceiver.length >= 3 && lowerClass.includes(lowerReceiver)) {
|
|
11877
11916
|
if (lowerReceiver.length >= 5 || lowerReceiver.length / lowerClass.length >= 0.4) {
|
|
11878
11917
|
return true;
|
|
11879
11918
|
}
|
|
11880
11919
|
}
|
|
11881
|
-
if (lowerReceiver.length >= 2) {
|
|
11920
|
+
if (!isAmbiguous && lowerReceiver.length >= 2) {
|
|
11882
11921
|
if (lowerClass.startsWith(lowerReceiver) || lowerClass.endsWith(lowerReceiver)) {
|
|
11883
11922
|
return true;
|
|
11884
11923
|
}
|
|
11885
11924
|
}
|
|
11886
|
-
if (lowerReceiver.length >= 3) {
|
|
11925
|
+
if (!isAmbiguous && lowerReceiver.length >= 3) {
|
|
11887
11926
|
const words = className.replace(/([a-z])([A-Z])/g, "$1\0$2").toLowerCase().split("\0");
|
|
11888
11927
|
for (const word of words) {
|
|
11889
11928
|
if (word.startsWith(lowerReceiver) && lowerReceiver.length / word.length >= 0.4) {
|
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.29.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",
|