Skip to content

Scan XML bodies from all Python XML parsers - #754

Open
iacobdaniel wants to merge 8 commits into
mainfrom
feat/hook-expat-on-xml-text
Open

iacobdaniel wants to merge 8 commits into
mainfrom
feat/hook-expat-on-xml-text

Conversation

@iacobdaniel

Copy link
Copy Markdown
Contributor

Apps that parse the XML request body with minidom, sax, pulldom, xmltodict or defusedxml (which Django REST framework's XML parser uses) were not protected: the values never reached the injection checks, so an attack in the XML body went through. Instead of hooking each of these libraries one by one, this hooks the single place they all go through to read XML, the creation of Python's built-in expat parser, so one hook covers all of them and any other library built on expat. ElementTree and lxml don't use that parser, so their existing hooks are extended from fromstring to XML, parse and iterparse. Only XML that is the request body is collected, and values are collected as they are parsed, so a query run inside a sax callback or an iterparse loop is checked too.

Comment thread aikido_zen/sources/xml_sources/lxml.py Outdated
Comment thread aikido_zen/sources/xml_sources/xml.py Outdated
for element in elements:
if isinstance(element.tag, str):
tag = element.tag
texts = (element.text, element.tail)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High - Split lxml text is not scanned as the value the app consumes

An attacker sends an XML body whose lxml text value is split around a child or comment, while the application builds a query from the element's composed itertext() value. The new walker stores only element.text and element.tail as separate fragments and never stores the composed text, so the SQL-injection sink scans different values from the one used by the application and a payload can reach the sink without detection.

Suggested change
texts = (element.text, element.tail)
texts = (element.text, element.tail, "".join(element.itertext()))

More info - Reply on this comment to give feedback or ignore the issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a regression. It will be handled in a separate PR.

Comment thread aikido_zen/sources/xml_sources/expat.py Outdated
@iacobdaniel iacobdaniel changed the title Scan XML bodies from every parser built on expat, and from ElementTree and lxml parse Scan XML bodies from all Python XML parsers Oct 14, 2026

This branch has not been deployed

No deployments
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.

1 participant