Skip to content

Detect local subclasses of Markup in B704#1446

Open
ChihebBENCHEIKH1 wants to merge 1 commit into
PyCQA:mainfrom
ChihebBENCHEIKH1:b704-detect-local-markup-subclasses
Open

Detect local subclasses of Markup in B704#1446
ChihebBENCHEIKH1 wants to merge 1 commit into
PyCQA:mainfrom
ChihebBENCHEIKH1:b704-detect-local-markup-subclasses

Conversation

@ChihebBENCHEIKH1

Copy link
Copy Markdown

Summary

B704 (markupsafe_markup_xss) only reports a call when the resolved name of the callee is one of the recognized Markup classes: markupsafe.Markup, flask.Markup, or a name listed under extend_markup_names. When a project defines its own subclass of Markup and passes dynamic data to it, the call is not reported. This is the false negative described in #1405 and tied to CVE-2025-54384.

Reproduction

from markupsafe import Markup


class Lit(Markup):
    pass


content = input()
Lit(f"unsafe {content}")   # not reported before this change

Before: only direct Markup(...) calls are reported.
After: calls to a local subclass of a Markup class are reported as well.

What changed

  • BanditNodeVisitor now records the resolved base classes of every class definition it walks, alongside the existing import tracking, and exposes them on the context as context.classes.
  • B704 walks that inheritance graph and treats a call to a local class that subclasses a Markup class, directly or through a chain of subclasses, the same way it treats a direct Markup call. Subclasses of a configured extend_markup_names entry are covered too.
  • The two example files gain direct, nested, and configured-name subclass cases, and the functional test counts are updated. A call with a constant argument stays unreported, so no false positives are introduced.

Testing

  • stestr run (full suite): 273 passing
  • flake8 bandit tests: clean
  • black, reorder-python-imports, pyupgrade: no changes
  • bandit -r bandit -ll -ii: no new findings

Resolves #1405

The B704 check only flagged calls whose resolved name was one of the
recognized Markup classes (markupsafe.Markup, flask.Markup, or a name
added through the plugin configuration). A project that wraps Markup in
its own subclass and then calls that subclass with dynamic data was not
flagged, which is the false negative behind CVE-2025-54384.

Track the base classes of every class definition while walking the
module and expose them on the test context. B704 now walks that
inheritance graph and treats a call to a local class that subclasses a
Markup class, directly or through a chain of subclasses, the same way it
treats a direct Markup call.

Extend the example files with direct, nested, and configured-name
subclasses and update the functional test counts accordingly.

Resolves: PyCQA#1405

Signed-off-by: chiheb ben cheikh <bencheikh.chiheb@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

B704 false negative for local Markup subclasses (CVE-2025-54384)

1 participant