2026-09-04 13:57:33 +02:00
|
|
|
version = "1"
|
|
|
|
|
language = "python"
|
|
|
|
|
|
|
|
|
|
[[source]]
|
|
|
|
|
id = "request"
|
|
|
|
|
patterns = [
|
|
|
|
|
"request.args",
|
|
|
|
|
"request.form",
|
|
|
|
|
"request.data",
|
|
|
|
|
"request.json",
|
|
|
|
|
"request.cookies",
|
|
|
|
|
"request.values",
|
|
|
|
|
"request.get_json",
|
|
|
|
|
"request.headers",
|
|
|
|
|
"request.files",
|
|
|
|
|
"request.get",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
[[source]]
|
|
|
|
|
id = "argv"
|
|
|
|
|
patterns = ["sys.argv"]
|
|
|
|
|
|
|
|
|
|
[[source]]
|
|
|
|
|
id = "stdin"
|
|
|
|
|
patterns = ["sys.stdin", "stdin.read"]
|
|
|
|
|
|
|
|
|
|
[[source]]
|
|
|
|
|
id = "input"
|
|
|
|
|
patterns = ["input("]
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
id = "eval"
|
|
|
|
|
cwe = "CWE-95"
|
|
|
|
|
calls = ["eval", "exec"]
|
|
|
|
|
rule_ids = ["python-unsafe-eval"]
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
id = "pickle.loads"
|
|
|
|
|
cwe = "CWE-502"
|
|
|
|
|
calls = ["pickle.loads", "pickle.load", "yaml.load", "marshal.loads", "cPickle.loads"]
|
|
|
|
|
rule_ids = ["python-unsafe-deserialization"]
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
id = "execute"
|
|
|
|
|
cwe = "CWE-89"
|
|
|
|
|
calls = ["execute", "executemany"]
|
|
|
|
|
rule_ids = ["python-sql-injection"]
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
id = "os.system"
|
|
|
|
|
cwe = "CWE-78"
|
|
|
|
|
calls = ["os.system", "os.popen", "subprocess.run", "subprocess.call", "subprocess.Popen", "subprocess.check_output"]
|
|
|
|
|
rule_ids = ["python-os-command", "python-shell-true"]
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
id = "hashlib"
|
|
|
|
|
cwe = "CWE-327"
|
|
|
|
|
calls = ["hashlib.md5", "hashlib.sha1", "hashlib.new"]
|
|
|
|
|
rule_ids = ["python-weak-hash"]
|
|
|
|
|
weak_literals = ["md5", "sha1", "MD5", "SHA1", "sha-1"]
|
|
|
|
|
|
|
|
|
|
[[sanitizer]]
|
|
|
|
|
id = "ast.literal_eval"
|
|
|
|
|
calls = ["ast.literal_eval"]
|
|
|
|
|
|
|
|
|
|
[[sanitizer]]
|
|
|
|
|
id = "yaml.safe_load"
|
|
|
|
|
calls = ["yaml.safe_load", "safe_load"]
|
|
|
|
|
|
|
|
|
|
[[sanitizer]]
|
|
|
|
|
id = "parameterized_execute"
|
|
|
|
|
calls = ["execute", "executemany"]
|
|
|
|
|
parameterized = true
|
2026-09-08 14:45:12 +02:00
|
|
|
|
|
|
|
|
# --- model-grounded-detection task 4.2 -------------------------------------------------------------------
|
|
|
|
|
# Sinks for the four families that previously had no fact routing to them by CWE, plus the ORM raw-SQL forms
|
|
|
|
|
# the Joern go/no-go measured as misses (11 of 23). Every entry below is a documented dangerous API of the
|
|
|
|
|
# named library, not an inferred pattern; the provenance is on each entry so a maintainer can review the data
|
|
|
|
|
# as data. `rule_ids` is left empty where no pattern rule exists: these facts feed the model layer, and a
|
|
|
|
|
# sink fact is not a detection rule.
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
# CWE-89. Django's documented raw-SQL escape hatches (docs: "Performing raw SQL queries") and the
|
|
|
|
|
# SQLAlchemy/peewee text forms. These were the single largest miss class in the go/no-go.
|
|
|
|
|
id = "orm.raw"
|
|
|
|
|
cwe = "CWE-89"
|
|
|
|
|
calls = ["objects.raw", "raw", "RawSQL", "extra", "text", "from_statement"]
|
|
|
|
|
rule_ids = []
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
# CWE-22. Filesystem entry points that accept a caller-supplied path: the stdlib openers plus Flask's
|
|
|
|
|
# send_file/send_from_directory and Django's FileResponse.
|
|
|
|
|
id = "path.open"
|
|
|
|
|
cwe = "CWE-22"
|
|
|
|
|
calls = ["open", "send_file", "send_from_directory", "FileResponse", "os.remove", "os.unlink", "shutil.copy", "shutil.move", "shutil.rmtree"]
|
|
|
|
|
rule_ids = []
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
# CWE-79. The documented "this string is trusted HTML" escapes: Jinja/Flask render_template_string and
|
|
|
|
|
# Markup, Django's mark_safe and format_html. Rendering a template *file* is not a sink; rendering a
|
|
|
|
|
# caller-supplied *string* is.
|
|
|
|
|
id = "html.unescaped"
|
|
|
|
|
cwe = "CWE-79"
|
|
|
|
|
calls = ["render_template_string", "Markup", "mark_safe", "format_html", "HttpResponse"]
|
|
|
|
|
rule_ids = []
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
# CWE-918 (SSRF) and CWE-601 (open redirect): outbound requests and redirects to a caller-supplied
|
|
|
|
|
# destination. requests/urllib/httpx are the documented HTTP clients; redirect is Flask's and Django's.
|
|
|
|
|
id = "outbound.request"
|
|
|
|
|
cwe = "CWE-918"
|
|
|
|
|
calls = ["requests.get", "requests.post", "requests.request", "urlopen", "urlretrieve", "httpx.get", "httpx.post"]
|
|
|
|
|
rule_ids = []
|
|
|
|
|
|
|
|
|
|
[[sink]]
|
|
|
|
|
id = "redirect"
|
|
|
|
|
cwe = "CWE-601"
|
|
|
|
|
calls = ["redirect", "HttpResponseRedirect", "url_for"]
|
|
|
|
|
rule_ids = []
|