XML From the Request Parsed With Entity Expansion
XML supplied by the caller is parsed with a parser that honours external entities.
Why it matters
XML has a feature for including other documents by reference. A parser that follows those references will happily read /etc/passwd or fetch an internal URL on the caller's behalf, and an entity that expands recursively turns a tiny document into gigabytes. defusedxml is the standard library's own parsers with those features switched off.
What it looks like
This is the shape of code that triggers the rule. AI tools produce it because it works, and nothing tells them it is unsafe.
import xml.etree.ElementTree as ET
root = ET.fromstring(request.data)The smallest fix
# Before
import xml.etree.ElementTree as ET
root = ET.fromstring(request.data)
# After
import defusedxml.ElementTree as ET
root = ET.fromstring(request.data)The better fix
If you have a few more minutes, this is the approach that holds up as the app grows.
# With lxml, build the parser explicitly:
parser = lxml.etree.XMLParser(resolve_entities=False, no_network=True, huge_tree=False)
root = lxml.etree.fromstring(request.data, parser)
# Better still, accept JSON for new endpoints.Let your AI tool fix it
When the scanner finds this in your project, it fills in the file and line for you. This is the prompt it gives you to paste into Claude Code, Cursor or whatever you use.
How to check the fix worked
1. Submit XML containing <!ENTITY x SYSTEM "file:///etc/hostname"> and confirm the request fails or the entity is not expanded. 2. Confirm a normal document still parses.