entrygraph 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. entrygraph/__init__.py +87 -0
  2. entrygraph/__main__.py +8 -0
  3. entrygraph/_version.py +24 -0
  4. entrygraph/api.py +549 -0
  5. entrygraph/cli/__init__.py +0 -0
  6. entrygraph/cli/main.py +387 -0
  7. entrygraph/cli/render.py +136 -0
  8. entrygraph/data/sinks/csharp.toml +106 -0
  9. entrygraph/data/sinks/go.toml +87 -0
  10. entrygraph/data/sinks/java.toml +92 -0
  11. entrygraph/data/sinks/javascript.toml +112 -0
  12. entrygraph/data/sinks/lib_javascript.toml +34 -0
  13. entrygraph/data/sinks/lib_python.toml +39 -0
  14. entrygraph/data/sinks/php.toml +125 -0
  15. entrygraph/data/sinks/python.toml +160 -0
  16. entrygraph/data/sinks/ruby.toml +102 -0
  17. entrygraph/data/sinks/rust.toml +68 -0
  18. entrygraph/db/__init__.py +0 -0
  19. entrygraph/db/engine.py +34 -0
  20. entrygraph/db/meta.py +70 -0
  21. entrygraph/db/models.py +176 -0
  22. entrygraph/db/queries.py +155 -0
  23. entrygraph/detect/__init__.py +0 -0
  24. entrygraph/detect/entrypoints/__init__.py +22 -0
  25. entrygraph/detect/entrypoints/base.py +124 -0
  26. entrygraph/detect/entrypoints/configs.py +139 -0
  27. entrygraph/detect/entrypoints/csharp.py +156 -0
  28. entrygraph/detect/entrypoints/golang.py +158 -0
  29. entrygraph/detect/entrypoints/java.py +187 -0
  30. entrygraph/detect/entrypoints/javascript.py +211 -0
  31. entrygraph/detect/entrypoints/php.py +133 -0
  32. entrygraph/detect/entrypoints/python.py +335 -0
  33. entrygraph/detect/entrypoints/ruby.py +147 -0
  34. entrygraph/detect/entrypoints/rust.py +153 -0
  35. entrygraph/detect/frameworks.py +369 -0
  36. entrygraph/detect/manifests.py +234 -0
  37. entrygraph/detect/taint.py +224 -0
  38. entrygraph/errors.py +27 -0
  39. entrygraph/extract/__init__.py +0 -0
  40. entrygraph/extract/base.py +51 -0
  41. entrygraph/extract/csharp.py +502 -0
  42. entrygraph/extract/golang.py +342 -0
  43. entrygraph/extract/ir.py +105 -0
  44. entrygraph/extract/java.py +329 -0
  45. entrygraph/extract/javascript.py +400 -0
  46. entrygraph/extract/php.py +426 -0
  47. entrygraph/extract/python.py +390 -0
  48. entrygraph/extract/registry.py +43 -0
  49. entrygraph/extract/ruby.py +321 -0
  50. entrygraph/extract/rust.py +482 -0
  51. entrygraph/fs/__init__.py +0 -0
  52. entrygraph/fs/hashing.py +78 -0
  53. entrygraph/fs/lang.py +134 -0
  54. entrygraph/fs/walker.py +167 -0
  55. entrygraph/graph/__init__.py +0 -0
  56. entrygraph/graph/adjacency.py +146 -0
  57. entrygraph/graph/cte.py +123 -0
  58. entrygraph/graph/scoring.py +101 -0
  59. entrygraph/kinds.py +51 -0
  60. entrygraph/parsing/__init__.py +0 -0
  61. entrygraph/parsing/parsers.py +49 -0
  62. entrygraph/parsing/queries.py +39 -0
  63. entrygraph/pipeline/__init__.py +0 -0
  64. entrygraph/pipeline/scanner.py +506 -0
  65. entrygraph/pipeline/worker.py +49 -0
  66. entrygraph/pipeline/writer.py +41 -0
  67. entrygraph/py.typed +0 -0
  68. entrygraph/queries/csharp/calls.scm +4 -0
  69. entrygraph/queries/csharp/definitions.scm +29 -0
  70. entrygraph/queries/csharp/imports.scm +4 -0
  71. entrygraph/queries/go/calls.scm +2 -0
  72. entrygraph/queries/go/definitions.scm +24 -0
  73. entrygraph/queries/go/imports.scm +1 -0
  74. entrygraph/queries/java/calls.scm +2 -0
  75. entrygraph/queries/java/definitions.scm +14 -0
  76. entrygraph/queries/java/imports.scm +2 -0
  77. entrygraph/queries/javascript/calls.scm +4 -0
  78. entrygraph/queries/javascript/definitions.scm +4 -0
  79. entrygraph/queries/javascript/imports.scm +6 -0
  80. entrygraph/queries/php/calls.scm +8 -0
  81. entrygraph/queries/php/definitions.scm +24 -0
  82. entrygraph/queries/php/imports.scm +1 -0
  83. entrygraph/queries/python/calls.scm +2 -0
  84. entrygraph/queries/python/definitions.scm +11 -0
  85. entrygraph/queries/python/imports.scm +2 -0
  86. entrygraph/queries/ruby/calls.scm +4 -0
  87. entrygraph/queries/ruby/definitions.scm +20 -0
  88. entrygraph/queries/ruby/imports.scm +7 -0
  89. entrygraph/queries/rust/calls.scm +5 -0
  90. entrygraph/queries/rust/definitions.scm +26 -0
  91. entrygraph/queries/rust/imports.scm +4 -0
  92. entrygraph/resolve/__init__.py +0 -0
  93. entrygraph/resolve/externals.py +61 -0
  94. entrygraph/resolve/hierarchy.py +152 -0
  95. entrygraph/resolve/resolver.py +275 -0
  96. entrygraph/resolve/symbol_table.py +48 -0
  97. entrygraph/results.py +138 -0
  98. entrygraph-0.1.0.dist-info/METADATA +204 -0
  99. entrygraph-0.1.0.dist-info/RECORD +102 -0
  100. entrygraph-0.1.0.dist-info/WHEEL +4 -0
  101. entrygraph-0.1.0.dist-info/entry_points.txt +2 -0
  102. entrygraph-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,87 @@
1
+ # Built-in Go sink/source catalog.
2
+ # Patterns are brace-globs matched against canonical callee qnames:
3
+ # import-expanded external calls -> "go:os/exec.Command"
4
+ # unresolved selector calls -> "go:*.Query"
5
+ # unresolved bare calls -> "go:panic"
6
+
7
+ [[sink]]
8
+ id = "go.command-exec.exec"
9
+ category = "command_exec"
10
+ severity = "high"
11
+ callee = "go:os/exec.{Command,CommandContext}"
12
+ description = "Subprocess execution via os/exec"
13
+
14
+ [[sink]]
15
+ id = "go.command-exec.os"
16
+ category = "command_exec"
17
+ severity = "high"
18
+ callee = "go:os.StartProcess"
19
+ description = "OS process spawn"
20
+
21
+ [[sink]]
22
+ id = "go.sql-query"
23
+ category = "sql"
24
+ severity = "medium"
25
+ callee = "go:*.{Query,QueryRow,Exec,QueryContext,ExecContext,QueryRowContext}"
26
+ description = "SQL statement execution (receiver-agnostic; database/sql)"
27
+
28
+ [[sink]]
29
+ id = "go.file-write"
30
+ category = "file_write"
31
+ severity = "low"
32
+ callee = "go:os.{OpenFile,WriteFile,Create,Remove,RemoveAll}"
33
+ description = "Filesystem mutation"
34
+
35
+ [[sink]]
36
+ id = "go.network-out"
37
+ category = "network_out"
38
+ severity = "low"
39
+ callee = "go:net/http.{Get,Post,PostForm,Head}"
40
+ description = "Outbound network request"
41
+
42
+ [[source]]
43
+ id = "go.nethttp.request"
44
+ category = "http_input"
45
+ callee = "go:*.{FormValue,PostFormValue,Query}"
46
+ description = "HTTP request input"
47
+
48
+ # --- C5 deepening ---
49
+ [[sink]]
50
+ id = "go.path-traversal"
51
+ category = "path_traversal"
52
+ severity = "medium"
53
+ callee = "go:{os.Open,os.ReadFile,io/ioutil.{ReadFile,WriteFile}}"
54
+ description = "File access (verify the path is not attacker-controlled)"
55
+
56
+ [[sink]]
57
+ id = "go.ssrf"
58
+ category = "ssrf"
59
+ severity = "medium"
60
+ callee = "go:net/http.{NewRequest,NewRequestWithContext}"
61
+ description = "Outbound HTTP request construction"
62
+
63
+ [[sink]]
64
+ id = "go.weak-crypto"
65
+ category = "weak_crypto"
66
+ severity = "low"
67
+ callee = "go:{crypto/md5.{New,Sum},crypto/sha1.{New,Sum},crypto/des.NewCipher,crypto/rc4.NewCipher,math/rand.{Int,Intn,Float64}}"
68
+ description = "Weak crypto or non-cryptographic RNG"
69
+
70
+ [[sink]]
71
+ id = "go.template-injection"
72
+ category = "template_injection"
73
+ severity = "medium"
74
+ callee = "go:text/template.{New,Must}"
75
+ description = "text/template (unescaped) rendering"
76
+
77
+ [[source]]
78
+ id = "go.gin.input"
79
+ category = "http_input"
80
+ callee = "go:*.{Param,GetHeader,Bind,BindJSON,ShouldBind,ShouldBindJSON}"
81
+ description = "Gin request input"
82
+
83
+ [[source]]
84
+ id = "go.env"
85
+ category = "env_input"
86
+ callee = "go:os.Getenv"
87
+ description = "Environment variable input"
@@ -0,0 +1,92 @@
1
+ # Built-in Java sink/source catalog.
2
+ # Patterns are brace-globs matched against canonical callee qnames:
3
+ # resolved external calls -> "java:com.example.Foo.bar"
4
+ # unresolved attribute calls -> "java:*.exec" (unknown receiver)
5
+ # unresolved bare calls -> "java:doThing"
6
+ #
7
+ # Runtime.getRuntime().exec(...) and new ProcessBuilder(...).start() both have
8
+ # unknown receivers, so they land on "java:*.exec" / "java:*.start"-style
9
+ # guesses; the receiver-agnostic patterns below catch them.
10
+
11
+ [[sink]]
12
+ id = "java.command-exec"
13
+ category = "command_exec"
14
+ severity = "high"
15
+ callee = "java:{*.exec,Runtime.exec,ProcessBuilder,*.ProcessBuilder}"
16
+ description = "OS command execution (Runtime.exec / ProcessBuilder)"
17
+
18
+ [[sink]]
19
+ id = "java.sql-execute"
20
+ category = "sql"
21
+ severity = "medium"
22
+ callee = "java:*.{executeQuery,executeUpdate,execute,executeLargeUpdate,executeBatch}"
23
+ description = "SQL statement execution (receiver-agnostic)"
24
+
25
+ [[sink]]
26
+ id = "java.deserialization"
27
+ category = "deserialization"
28
+ severity = "high"
29
+ callee = "java:*.readObject"
30
+ description = "Unsafe Java deserialization (ObjectInputStream.readObject)"
31
+
32
+ [[sink]]
33
+ id = "java.code-eval"
34
+ category = "code_eval"
35
+ severity = "critical"
36
+ callee = "java:*.eval"
37
+ description = "Dynamic code evaluation (ScriptEngine.eval)"
38
+
39
+ # --- C5 deepening ---
40
+ [[sink]]
41
+ id = "java.ssrf"
42
+ category = "ssrf"
43
+ severity = "medium"
44
+ callee = "java:*.{openConnection,openStream}"
45
+ description = "Outbound connection (URL.openConnection / openStream)"
46
+
47
+ [[sink]]
48
+ id = "java.xxe"
49
+ category = "xxe"
50
+ severity = "medium"
51
+ callee = "java:*.{newDocumentBuilder,newSAXParser,newXMLReader,createXMLStreamReader}"
52
+ description = "XML parser factory susceptible to XXE"
53
+
54
+ [[sink]]
55
+ id = "java.deserialization.extra"
56
+ category = "deserialization"
57
+ severity = "high"
58
+ callee = "java:{XMLDecoder,*.XMLDecoder,*.readUnshared,*.enableDefaultTyping}"
59
+ description = "Unsafe deserialization (XMLDecoder / Jackson default typing)"
60
+
61
+ [[sink]]
62
+ id = "java.jndi"
63
+ category = "jndi"
64
+ severity = "medium"
65
+ callee = "java:*.lookup"
66
+ description = "JNDI lookup (InitialContext.lookup)"
67
+
68
+ [[sink]]
69
+ id = "java.expression-injection"
70
+ category = "template_injection"
71
+ severity = "high"
72
+ callee = "java:*.{parseExpression,evaluate,createTemplate}"
73
+ description = "Expression/template evaluation (SpEL / Velocity / Freemarker)"
74
+
75
+ [[sink]]
76
+ id = "java.path-traversal"
77
+ category = "path_traversal"
78
+ severity = "medium"
79
+ callee = "java:{FileInputStream,*.FileInputStream,FileReader,*.FileReader,Files.readAllBytes,*.Files.readAllBytes,Paths.get}"
80
+ description = "File access with a potentially attacker-controlled path"
81
+
82
+ [[source]]
83
+ id = "java.servlet.input"
84
+ category = "http_input"
85
+ callee = "java:*.{getParameter,getParameterValues,getHeader,getQueryString,getInputStream,getReader,getCookies}"
86
+ description = "Servlet request input"
87
+
88
+ [[source]]
89
+ id = "java.env"
90
+ category = "env_input"
91
+ callee = "java:System.getenv"
92
+ description = "Environment variable input"
@@ -0,0 +1,112 @@
1
+ # Built-in JavaScript / TypeScript sink catalog.
2
+ # Canonical callees: import-expanded externals like "js:child_process.exec",
3
+ # unresolved attribute calls like "js:*.query", bare calls like "js:eval".
4
+
5
+ [[sink]]
6
+ id = "js.command-exec.child_process"
7
+ category = "command_exec"
8
+ severity = "high"
9
+ callee = "js:child_process.{exec,execSync,spawn,spawnSync,execFile,execFileSync}"
10
+ description = "Child process execution"
11
+
12
+ [[sink]]
13
+ id = "js.command-exec.member"
14
+ category = "command_exec"
15
+ severity = "high"
16
+ callee = "js:*.{exec,execSync,spawn,spawnSync}"
17
+ description = "Child process execution (member call)"
18
+
19
+ [[sink]]
20
+ id = "js.code-eval"
21
+ category = "code_eval"
22
+ severity = "critical"
23
+ callee = "js:{eval,Function}"
24
+ description = "Dynamic code evaluation"
25
+
26
+ [[sink]]
27
+ id = "js.sql-query"
28
+ category = "sql"
29
+ severity = "medium"
30
+ callee = "js:*.{query,execute,raw}"
31
+ description = "SQL query execution (receiver-agnostic)"
32
+
33
+ [[sink]]
34
+ id = "js.file-write"
35
+ category = "file_write"
36
+ severity = "low"
37
+ callee = "js:{fs.writeFile,fs.writeFileSync,fs.appendFile,fs.rm,fs.rmSync,fs.unlink}"
38
+ description = "Filesystem mutation"
39
+
40
+ [[sink]]
41
+ id = "js.network-out"
42
+ category = "network_out"
43
+ severity = "low"
44
+ callee = "js:{fetch,axios.get,axios.post,http.get,https.get}"
45
+ description = "Outbound network request"
46
+
47
+ [[source]]
48
+ id = "js.express.req"
49
+ category = "http_input"
50
+ callee = "js:*.{body,query,params}"
51
+ description = "Express request input"
52
+
53
+ # --- sanitizers (S3): neutralize/reduce taint for a sink category ---
54
+ [[sanitizer]]
55
+ id = "js.sanitize.sqlstring"
56
+ category = "sql"
57
+ callee = "js:{sqlstring.escape,mysql.escape,*.escapeId,*.escape}"
58
+ effect = "reduces"
59
+ description = "SQL string escaping"
60
+
61
+ [[sanitizer]]
62
+ id = "js.sanitize.shellescape"
63
+ category = "command_exec"
64
+ callee = "js:{shell-quote.quote,shellescape}"
65
+ effect = "neutralizes"
66
+ description = "Shell argument quoting"
67
+
68
+ [[sanitizer]]
69
+ id = "js.sanitize.html-escape"
70
+ category = "template_injection"
71
+ callee = "js:{escape-html,he.encode,*.escapeHtml}"
72
+ effect = "reduces"
73
+ description = "HTML entity escaping"
74
+
75
+ # --- C5 deepening ---
76
+ [[sink]]
77
+ id = "js.ssrf"
78
+ category = "ssrf"
79
+ severity = "medium"
80
+ callee = "js:{axios.{request,put,delete,patch},got,http.request,https.request,undici.{request,fetch}}"
81
+ require_arg_hint = "\\+|\\$\\{|`"
82
+ description = "Server-side request with a non-literal URL"
83
+
84
+ [[sink]]
85
+ id = "js.path-traversal"
86
+ category = "path_traversal"
87
+ severity = "medium"
88
+ callee = "js:fs.{readFile,readFileSync,createReadStream,open,openSync}"
89
+ require_arg_hint = "\\+|\\$\\{|`"
90
+ description = "File read with a non-literal path"
91
+
92
+ [[sink]]
93
+ id = "js.template-injection"
94
+ category = "template_injection"
95
+ severity = "high"
96
+ callee = "js:{ejs.render,handlebars.compile,pug.render,nunjucks.renderString,lodash.template}"
97
+ description = "Template rendering / compilation"
98
+
99
+ [[sink]]
100
+ id = "js.code-eval.vm"
101
+ category = "code_eval"
102
+ severity = "critical"
103
+ callee = "js:vm.{runInNewContext,runInThisContext,runInContext}"
104
+ description = "Node vm dynamic code execution"
105
+
106
+ [[sink]]
107
+ id = "js.weak-crypto"
108
+ category = "weak_crypto"
109
+ severity = "low"
110
+ callee = "js:crypto.createHash"
111
+ require_arg_hint = "md5|sha1"
112
+ description = "Weak hashing algorithm"
@@ -0,0 +1,34 @@
1
+ # Library summaries for JS/TS third-party wrappers. See lib_python.toml header.
2
+
3
+ [[sink]]
4
+ id = "lib.js.knex.raw"
5
+ category = "sql"
6
+ severity = "medium"
7
+ callee = "js:{knex.raw,*.knex.raw}"
8
+ description = "Knex raw SQL query"
9
+ library = "knex"
10
+ require_arg_hint = "\\+|\\$\\{|`"
11
+
12
+ [[sink]]
13
+ id = "lib.js.sequelize.query"
14
+ category = "sql"
15
+ severity = "medium"
16
+ callee = "js:{sequelize.query,*.sequelize.query}"
17
+ description = "Sequelize raw query"
18
+ library = "sequelize"
19
+
20
+ [[sink]]
21
+ id = "lib.js.shelljs.exec"
22
+ category = "command_exec"
23
+ severity = "high"
24
+ callee = "js:{shelljs.exec,shell.exec,*.shelljs.exec}"
25
+ description = "ShellJS command execution"
26
+ library = "shelljs"
27
+
28
+ [[sink]]
29
+ id = "lib.js.execa"
30
+ category = "command_exec"
31
+ severity = "high"
32
+ callee = "js:{execa,execa.command,execa.sync,execa.commandSync}"
33
+ description = "execa subprocess execution"
34
+ library = "execa"
@@ -0,0 +1,39 @@
1
+ # Library summaries: known third-party wrappers that reach a dangerous sink
2
+ # internally. entrygraph stops at the repo boundary, so a call into one of these
3
+ # would otherwise terminate at the wrapper. Modelled as ordinary sinks keyed on
4
+ # the wrapper's canonical callee, with `library` set for provenance.
5
+ #
6
+ # Rule of thumb: receiver-agnostic `*.name` patterns only for DISTINCTIVE method
7
+ # names; generic names must be module-qualified.
8
+
9
+ [[sink]]
10
+ id = "lib.py.fabric.run"
11
+ category = "command_exec"
12
+ severity = "high"
13
+ callee = "py:{fabric.api.run,fabric.api.sudo,fabric.api.local,fabric.operations.run,fabric.operations.sudo,*.Connection.run,*.Connection.sudo}"
14
+ description = "Fabric remote/local command execution"
15
+ library = "fabric"
16
+
17
+ [[sink]]
18
+ id = "lib.py.paramiko.exec"
19
+ category = "command_exec"
20
+ severity = "high"
21
+ callee = "py:*.exec_command"
22
+ description = "Paramiko SSH remote command execution"
23
+ library = "paramiko"
24
+
25
+ [[sink]]
26
+ id = "lib.py.sh"
27
+ category = "command_exec"
28
+ severity = "high"
29
+ callee = "py:{sh.Command,sh.bash,sh.sh}"
30
+ description = "sh module dynamic command invocation"
31
+ library = "sh"
32
+
33
+ [[sink]]
34
+ id = "lib.py.invoke.run"
35
+ category = "command_exec"
36
+ severity = "high"
37
+ callee = "py:{invoke.run,invoke.sudo,*.Context.run,*.Context.sudo}"
38
+ description = "Invoke task-runner command execution"
39
+ library = "invoke"
@@ -0,0 +1,125 @@
1
+ # Built-in PHP sink/source catalog.
2
+ # Patterns are brace-globs matched against canonical callee qnames:
3
+ # resolved external calls -> "php:App.Services.Runner.run"
4
+ # unresolved receiver calls -> "php:*.query"
5
+ # unresolved bare calls -> "php:shell_exec"
6
+ #
7
+ # Namespace separators (`\`) are normalized to `.` upstream, so globs are
8
+ # dot-based. NOTE: `$_GET` / `$_POST` / `$_REQUEST` / `$_COOKIE` superglobals
9
+ # are *variable reads*, not function calls, so they never surface as call
10
+ # references and cannot be modeled as sources here — taint from them must be
11
+ # tracked structurally, which is out of scope for this catalog.
12
+
13
+ [[sink]]
14
+ id = "php.command-exec"
15
+ category = "command_exec"
16
+ severity = "high"
17
+ callee = "php:{exec,system,shell_exec,passthru,popen,proc_open,pcntl_exec}"
18
+ description = "OS command execution"
19
+
20
+ [[sink]]
21
+ id = "php.code-eval"
22
+ category = "code_eval"
23
+ severity = "critical"
24
+ callee = "php:{eval,assert,create_function}"
25
+ description = "Dynamic code evaluation"
26
+
27
+ [[sink]]
28
+ id = "php.code-eval.callback"
29
+ category = "code_eval"
30
+ severity = "critical"
31
+ callee = "php:{call_user_func,call_user_func_array}"
32
+ require_arg_hint = "\\$"
33
+ description = "Dynamic callback invocation with a non-literal callable"
34
+
35
+ [[sink]]
36
+ id = "php.code-inclusion"
37
+ category = "code_inclusion"
38
+ severity = "critical"
39
+ callee = "php:{include,include_once,require,require_once}"
40
+ require_arg_hint = "\\$"
41
+ description = "Dynamic file inclusion with a non-literal path"
42
+
43
+ [[sink]]
44
+ id = "php.deserialization"
45
+ category = "deserialization"
46
+ severity = "high"
47
+ callee = "php:unserialize"
48
+ description = "Unsafe deserialization"
49
+
50
+ [[sink]]
51
+ id = "php.sql"
52
+ category = "sql"
53
+ severity = "high"
54
+ callee = "php:{mysqli_query,mysqli_multi_query,pg_query,sqlite_query}"
55
+ description = "SQL statement execution"
56
+
57
+ [[sink]]
58
+ id = "php.sql.pdo-query"
59
+ category = "sql"
60
+ severity = "high"
61
+ callee = "php:*.{query,exec}"
62
+ description = "PDO/DB query execution (receiver-agnostic)"
63
+
64
+ [[sink]]
65
+ id = "php.sql.pdo-prepare"
66
+ category = "sql"
67
+ severity = "low"
68
+ callee = "php:*.prepare"
69
+ description = "PDO prepared statement (receiver-agnostic)"
70
+
71
+ [[sink]]
72
+ id = "php.path-traversal"
73
+ category = "path_traversal"
74
+ severity = "medium"
75
+ callee = "php:{file_get_contents,file_put_contents,fopen,readfile,unlink}"
76
+ require_arg_hint = "\\$"
77
+ description = "Filesystem access with a non-literal path"
78
+
79
+ [[sink]]
80
+ id = "php.ssrf"
81
+ category = "ssrf"
82
+ severity = "medium"
83
+ callee = "php:{curl_exec,curl_init,fsockopen}"
84
+ description = "Server-side request"
85
+
86
+ [[sink]]
87
+ id = "php.template-injection"
88
+ category = "template_injection"
89
+ severity = "high"
90
+ callee = "php:*.render"
91
+ require_arg_hint = "\\$"
92
+ description = "Template rendering with non-literal input (receiver-agnostic)"
93
+
94
+ [[sink]]
95
+ id = "php.ldap"
96
+ category = "ldap"
97
+ severity = "medium"
98
+ callee = "php:{ldap_search,ldap_bind}"
99
+ description = "LDAP operation"
100
+
101
+ [[sink]]
102
+ id = "php.xxe"
103
+ category = "xxe"
104
+ severity = "medium"
105
+ callee = "php:{simplexml_load_string,simplexml_load_file}"
106
+ description = "XML parsing susceptible to XXE"
107
+
108
+ [[sink]]
109
+ id = "php.weak-crypto"
110
+ category = "weak_crypto"
111
+ severity = "low"
112
+ callee = "php:{md5,sha1,mt_rand,rand}"
113
+ description = "Weak hashing / insecure randomness"
114
+
115
+ [[source]]
116
+ id = "php.filter-input"
117
+ category = "http_input"
118
+ callee = "php:{filter_input,filter_input_array}"
119
+ description = "Filtered request input"
120
+
121
+ [[source]]
122
+ id = "php.laravel.request"
123
+ category = "http_input"
124
+ callee = "php:*.{input,query,post,cookie,header}"
125
+ description = "Laravel request accessors"
@@ -0,0 +1,160 @@
1
+ # Built-in Python sink/source catalog.
2
+ # Patterns are brace-globs matched against canonical callee qnames:
3
+ # resolved external calls -> "py:subprocess.run"
4
+ # unresolved attribute calls -> "py:*.execute"
5
+ # unresolved bare calls -> "py:eval"
6
+
7
+ [[sink]]
8
+ id = "py.command-exec.subprocess"
9
+ category = "command_exec"
10
+ severity = "high"
11
+ callee = "py:subprocess.{run,call,check_call,check_output,Popen,getoutput,getstatusoutput}"
12
+ description = "Subprocess execution"
13
+
14
+ [[sink]]
15
+ id = "py.command-exec.os"
16
+ category = "command_exec"
17
+ severity = "high"
18
+ callee = "py:os.{system,popen,execv,execve,execvp,execl,execlp,spawnv,spawnl,startfile}"
19
+ description = "OS command execution"
20
+
21
+ [[sink]]
22
+ id = "py.code-eval"
23
+ category = "code_eval"
24
+ severity = "critical"
25
+ callee = "py:{eval,exec,compile,builtins.eval,builtins.exec}"
26
+ description = "Dynamic code evaluation"
27
+
28
+ [[sink]]
29
+ id = "py.sql-execute"
30
+ category = "sql"
31
+ severity = "medium"
32
+ callee = "py:*.{execute,executemany,executescript}"
33
+ description = "SQL statement execution (receiver-agnostic)"
34
+
35
+ [[sink]]
36
+ id = "py.deserialization.pickle"
37
+ category = "deserialization"
38
+ severity = "high"
39
+ callee = "py:{pickle,cPickle,marshal,shelve}.{load,loads,open}"
40
+ description = "Unsafe deserialization"
41
+
42
+ [[sink]]
43
+ id = "py.deserialization.yaml"
44
+ category = "deserialization"
45
+ severity = "high"
46
+ callee = "py:yaml.{load,unsafe_load,full_load}"
47
+ description = "Unsafe YAML loading"
48
+
49
+ [[sink]]
50
+ id = "py.template-injection.flask"
51
+ category = "template_injection"
52
+ severity = "high"
53
+ callee = "py:{flask.render_template_string,*.render_template_string}"
54
+ description = "Template rendering from a string"
55
+
56
+ [[sink]]
57
+ id = "py.file-write"
58
+ category = "file_write"
59
+ severity = "low"
60
+ callee = "py:{shutil.rmtree,shutil.move,os.remove,os.unlink,os.rmdir,*.write_text,*.write_bytes}"
61
+ description = "Filesystem mutation"
62
+
63
+ [[sink]]
64
+ id = "py.network-out"
65
+ category = "network_out"
66
+ severity = "low"
67
+ callee = "py:{requests.{get,post,put,delete,patch,request},urllib.request.urlopen,httpx.{get,post,request}}"
68
+ description = "Outbound network request"
69
+
70
+ [[source]]
71
+ id = "py.flask.request"
72
+ category = "http_input"
73
+ callee = "py:flask.request*"
74
+ description = "Flask request object"
75
+
76
+ [[source]]
77
+ id = "py.stdin"
78
+ category = "user_input"
79
+ callee = "py:{input,sys.stdin.*}"
80
+ description = "Interactive input"
81
+
82
+ # --- sanitizers (S3) ---
83
+ [[sanitizer]]
84
+ id = "py.sanitize.shlex"
85
+ category = "command_exec"
86
+ callee = "py:shlex.{quote,split}"
87
+ effect = "neutralizes"
88
+ description = "Shell argument quoting"
89
+
90
+ [[sanitizer]]
91
+ id = "py.sanitize.markupsafe"
92
+ category = "template_injection"
93
+ callee = "py:{markupsafe.escape,markupsafe.escape_silent,html.escape,*.escape}"
94
+ effect = "reduces"
95
+ description = "HTML/template escaping"
96
+
97
+ [[sanitizer]]
98
+ id = "py.sanitize.shutil-which"
99
+ category = "command_exec"
100
+ callee = "py:shutil.which"
101
+ effect = "reduces"
102
+ description = "Resolving an executable path via allowlist lookup"
103
+
104
+ # --- C5 deepening ---
105
+ [[sink]]
106
+ id = "py.ssrf"
107
+ category = "ssrf"
108
+ severity = "medium"
109
+ callee = "py:{requests.{get,post,put,delete,patch,request},urllib.request.{urlopen,Request},httpx.{get,post,request,stream}}"
110
+ require_arg_hint = "\\+|%|format|f['\"]"
111
+ description = "Server-side request with a non-literal URL"
112
+
113
+ [[sink]]
114
+ id = "py.path-traversal"
115
+ category = "path_traversal"
116
+ severity = "medium"
117
+ callee = "py:{open,io.open}"
118
+ require_arg_hint = "\\+|%|format\\(|f['\"]"
119
+ description = "File open with a non-literal path"
120
+
121
+ [[sink]]
122
+ id = "py.xxe"
123
+ category = "xxe"
124
+ severity = "medium"
125
+ callee = "py:{xml.etree.ElementTree.{parse,fromstring},lxml.etree.{parse,fromstring,XML},xml.dom.minidom.{parse,parseString},xml.sax.{parse,parseString}}"
126
+ description = "XML parsing susceptible to XXE"
127
+
128
+ [[sink]]
129
+ id = "py.weak-crypto"
130
+ category = "weak_crypto"
131
+ severity = "low"
132
+ callee = "py:hashlib.{md5,sha1}"
133
+ description = "Weak hashing algorithm"
134
+
135
+ [[sink]]
136
+ id = "py.deserialization.extra"
137
+ category = "deserialization"
138
+ severity = "high"
139
+ callee = "py:{dill,cloudpickle,joblib}.{load,loads}"
140
+ description = "Unsafe deserialization (dill/cloudpickle/joblib)"
141
+
142
+ [[sink]]
143
+ id = "py.template-injection.libs"
144
+ category = "template_injection"
145
+ severity = "high"
146
+ callee = "py:{jinja2.Template,mako.template.Template,django.template.Template}"
147
+ description = "Template constructed from a string"
148
+
149
+ [[sink]]
150
+ id = "py.dynamic-import"
151
+ category = "code_eval"
152
+ severity = "medium"
153
+ callee = "py:{importlib.import_module,__import__}"
154
+ description = "Dynamic module import"
155
+
156
+ [[source]]
157
+ id = "py.env"
158
+ category = "env_input"
159
+ callee = "py:{os.getenv,os.environ.get}"
160
+ description = "Environment variable input"