Describe the bug
B704 catches direct use of markupsafe.Markup / flask.Markup, but it misses the same pattern when a project wraps Markup in a local subclass.
That causes false negatives on real CVE code. One example is CVE-2025-54384 in CKAN and CVE-2025-64187 in OctoPrint: user-controlled HTML is processed, insufficiently sanitized, and then wrapped in a local literal(Markup) class. Stock Bandit does not report these.
Reproduction steps
import re
from markdown import markdown
from markupsafe import Markup
RE_MD_HTML_TAGS = re.compile(r"<[^><]*>")
class literal(Markup):
pass
def markdown_extract(text):
plain = RE_MD_HTML_TAGS.sub("", markdown(text))
return literal(plain)
Run Bandit on this file with the stock ruleset.
Expected behavior
I would expect a B704-style finding here.
This is the same unsafe sink as Markup(...), just behind a local subclass. It seems reasonable for B704 to handle simple subclasses / wrappers of markupsafe.Markup, not only exact qualified names.
Bandit version
1.9.1 (Default)
Python version
3.10
Additional context
No response
Describe the bug
B704catches direct use ofmarkupsafe.Markup/flask.Markup, but it misses the same pattern when a project wrapsMarkupin a local subclass.That causes false negatives on real CVE code. One example is
CVE-2025-54384in CKAN andCVE-2025-64187in OctoPrint: user-controlled HTML is processed, insufficiently sanitized, and then wrapped in a localliteral(Markup)class. Stock Bandit does not report these.Reproduction steps
Expected behavior
I would expect a
B704-style finding here.This is the same unsafe sink as
Markup(...), just behind a local subclass. It seems reasonable forB704to handle simple subclasses / wrappers ofmarkupsafe.Markup, not only exact qualified names.Bandit version
1.9.1 (Default)
Python version
3.10
Additional context
No response