A feature of XML, not a bug
XXE differs from every other injection in this module in one important way: you concatenate nothing. No line of your code joins data into syntax. You call XmlDocument.Load(stream) — and the hole comes from the library default.
The cause is a genuine XML feature: the external entity. An XML document may declare an entity pointing at an external resource, and a standards-compliant parser fetches it.
<?xml version="1.0"?><!DOCTYPE r [ <!ENTITY x SYSTEM "file:///etc/passwd">]><r>&x;</r>The parser reads that file and substitutes its content where &x; appears. If your application echoes the XML content back — or merely puts it in an error message — then /etc/passwd has left the building.
Three consequences, in order of severity, and the third is the one people do not think of:
| Consequence | Mechanism |
|---|---|
| Reading server files | SYSTEM "file:///..." |
| SSRF | SYSTEM "http://169.254.169.254/..." — the parser becomes your HTTP client |
| DoS | Billion laughs: nested entities expand exponentially, a few KB into several GB of memory |
The second is where XXE and SSRF meet, and in a cloud environment it is worse than reading files: the parser can reach the cloud metadata endpoint, which the attacker cannot reach from outside.
The good news about .NET, and this is worth knowing precisely: since .NET Framework 4.5.2 and throughout .NET Core/.NET 5+, XmlDocument, XmlReader and XDocument are safe by default — DtdProcessing is Prohibit and XmlResolver is null. Which means XXE in modern .NET is almost always the result of somebody turning it on, usually because a legitimate XML file needed a DTD and the fastest way to make it work was to open everything.
That is why this lesson is about reading configuration rather than finding concatenation.
Comments
Commenting needs an account with at least one completed lesson. That condition is what keeps this thread worth reading: every point belongs to someone who can be asked back, and reputation accrues over time.
You can still read every comment below without an account. Signing in brings you back to this exact spot, not to the top of the page.
Loading comments…