Is your feature request related to a problem? Please describe.
Yes. Bandit currently misses a common SSRF pattern in Python services: user-controlled URLs from request data flowing into outbound HTTP clients such as requests, httpx, or urllib.
The existing HTTP-related plugins do not really cover this:
B113 checks missing timeout
B501 checks verify=False
B615 is specific to Hugging Face downloads
So in practice, Bandit can miss real SSRF bugs in code that downloads files or resources from user-provided URLs.
A concrete example is CVE-2025-54381 in BentoML:
- Advisory:
https://github.com/advisories/GHSA-mrmq-3q62-6cc8
- Fix:
https://github.com/bentoml/BentoML/commit/534c3584621da4ab954bdc3d814cc66b95ae5fb8
Similar issues also show up in projects like LLaMA-Factory (CVE-2025-61784), LNbits (CVE-2025-32013), and D-Tale (CVE-2024-21642).
Describe the solution you'd like
I would like Bandit to have a plugin for SSRF-style flows where:
- the source is request-controlled input such as
request.body(), request.args, request.form(), request.query_params, or request.get_json()
- the sink is an outbound HTTP call such as:
requests.*
httpx.*
urllib.request.urlopen
aiohttp.ClientSession.*
It would also be useful if the plugin understood common safety guards, for example helpers like is_safe_url(url) or similar allowlist/private-address checks, so fixed code does not keep getting flagged.
Describe alternatives you've considered
A few alternatives came up:
- Relying on existing Bandit plugins: this does not solve the problem, because the current plugins around HTTP calls check hygiene issues, not untrusted URL flow.
- Keeping this in heavier dataflow tools only, such as CodeQL: that works, but Bandit is often used as a lightweight scanner, and this is a common enough pattern that it would be valuable to catch here too.
- A broader "untrusted data to external API" plugin: I tried that approach, but it produced noise by flagging non-network calls. Narrowing it to real network sinks worked much better.
The plugin prototype I implemented was inspired by CodeQL’s rule py/count-untrusted-data-external-api.
It works well on my projects, and it successfully detects CVE-2025-54381 and CVE-2025-61784 and avoids FPs in their fixed commits.
external-api-untrusted-data.zip
Is your feature request related to a problem? Please describe.
Yes. Bandit currently misses a common SSRF pattern in Python services: user-controlled URLs from request data flowing into outbound HTTP clients such as
requests,httpx, orurllib.The existing HTTP-related plugins do not really cover this:
B113checks missingtimeoutB501checksverify=FalseB615is specific to Hugging Face downloadsSo in practice, Bandit can miss real SSRF bugs in code that downloads files or resources from user-provided URLs.
A concrete example is
CVE-2025-54381in BentoML:https://github.com/advisories/GHSA-mrmq-3q62-6cc8https://github.com/bentoml/BentoML/commit/534c3584621da4ab954bdc3d814cc66b95ae5fb8Similar issues also show up in projects like LLaMA-Factory (CVE-2025-61784), LNbits (CVE-2025-32013), and D-Tale (CVE-2024-21642).
Describe the solution you'd like
I would like Bandit to have a plugin for SSRF-style flows where:
request.body(),request.args,request.form(),request.query_params, orrequest.get_json()requests.*httpx.*urllib.request.urlopenaiohttp.ClientSession.*It would also be useful if the plugin understood common safety guards, for example helpers like
is_safe_url(url)or similar allowlist/private-address checks, so fixed code does not keep getting flagged.Describe alternatives you've considered
A few alternatives came up:
The plugin prototype I implemented was inspired by CodeQL’s rule
py/count-untrusted-data-external-api.It works well on my projects, and it successfully detects
CVE-2025-54381andCVE-2025-61784and avoids FPs in their fixed commits.external-api-untrusted-data.zip