PyCQA / PyCQA/bandit

Proposal: Detecting Flask file-serving API misuse

Open
#1,403 1 comment 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Python
Stars
8.3k
Forks
836
Avg merge
5d 3h
Merged PRs (30d)
1

Description

Is your feature request related to a problem? Please describe.
Yes. I'm using Bandit on Flask code and ran into a gap around send_file().

Bandit already has targeted plugins for specific risky APIs and framework misuse, for example B201 for Flask debug mode and B202 for unsafe tarfile.extractall(). But there does not seem to be a similar plugin for a very common Flask pattern: passing a request-controlled path into send_file().

A real example is CVE-2025-6166 in Agent-Zero:

path = input.get("path", request.args.get("path", ""))
if not path:
    raise ValueError("No path provided")
return send_file(path)

This ended up as a false negative in my Bandit baseline run, even though it is a straightforward arbitrary file read / path traversal case.

Similar Flask send_file traversal cases also exist in:

  • CVE-2022-31583
  • CVE-2022-31549
  • CVE-2022-31506

Describe the solution you'd like
I'd like a small Flask-specific plugin that warns when send_file() is called with a path taken directly from common request accessors such as:

  • request.args.get(...)
  • request.form.get(...)
  • request.values.get(...)

A minimal first version could stay narrow and only cover:

  • direct use inside the call, or
  • a simple local assignment right before the call

For example:

return send_file(request.args.get("path"))

or

path = request.args.get("path")
return send_file(path)

This feels similar in spirit to other Bandit plugins that target one dangerous API pattern without trying to do full taint tracking.

Describe alternatives you've considered
I first looked for an existing Bandit plugin that could be extended, but I couldn't find one that was close enough. B202 is the nearest match conceptually because it covers a path-traversal-style misuse of a specific API, but it is limited to archive extraction.

I also considered asking for a more general request-to-file-path plugin, but that seems broader than Bandit's scope. A narrow send_file() plugin looks like the smallest useful change.

Additional context
I implemented a plugin prototype according to one of CodeQL's rules for Flask, which could be used as a reference. It worked well on my project, and could detect CVE-2025-6166 and CVE-2022-31549 with no FPs on fixed commits.

flask-secure-static-file.zip

Love this idea? Give it a 👍. We prioritize fulfilling features with the most 👍.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing Bandit's existing Flask and API-misuse plugins, especially B201 and B202, then compare the attached flask-secure-static-file.zip prototype with those patterns. Done means a narrow plugin recognizes direct request.args.get(), request.form.get(), or request.values.get() use in send_file(), plus the described simple local assignment case.

Written by the indexing model from the issue text.

Assessment

Tech stack
flask, python
Domain
security, tooling
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
67/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.