Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

Intro to XXE Injection

XML External Entity (XXE) Injection occurs when user-controlled XML input is parsed without proper sanitization, allowing an attacker to leverage XML features for malicious actions — from disclosing sensitive server files to shutting down the back-end. Ranked in OWASP’s Top 10.

XML primer

XML (Extensible Markup Language) is designed for flexible data storage and transfer, not display. Documents are element trees: one root element, with child elements nested inside.

Basic example:

<?xml version="1.0" encoding="UTF-8"?>
<email>
  <date>01-01-2022</date>
  <time>10:00 am UTC</time>
  <sender>john@inlanefreight.com</sender>
  <recipients>
    <to>HR@inlanefreight.com</to>
    <cc>
      <to>billing@inlanefreight.com</to>
    </cc>
  </recipients>
  <body>Hello, please share the invoice. Regards, John</body>
</email>

Key XML terms

TermDefinitionExample
TagKeys of an XML document, wrapped with </><date>
EntityXML variables, wrapped with &/;&lt;
ElementA tag and its stored value<date>01-01-2022</date>
AttributeOptional specifications inside a tagversion="1.0"
DeclarationFirst line, defines XML version/encoding<?xml version="1.0" encoding="UTF-8"?>

Reserved characters (<, >, &, ") must be written as entity references (&lt;, &gt;, &amp;, &quot;) when used as data. Comments: <!-- comment -->.

XML DTD

A Document Type Definition (DTD) validates an XML document against a pre-defined structure. It can be declared inline or in an external file.

Inline example:

<!DOCTYPE email [
  <!ELEMENT email (date, time, sender, recipients, body)>
  <!ELEMENT recipients (to, cc?)>
  <!ELEMENT date (#PCDATA)>
  <!ELEMENT sender (#PCDATA)>
  <!ELEMENT body (#PCDATA)>
]>

External file reference (using SYSTEM):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email SYSTEM "email.dtd">

External URL reference:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email SYSTEM "http://inlanefreight.com/email.dtd">

XML entities

Custom entities (variables) can be defined in a DTD with the ENTITY keyword:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
  <!ENTITY company "Inlane Freight">
]>

Reference with &company; — the parser substitutes the value at parse time.

External entities — the XXE primitive

Entities can reference external files or URLs via the SYSTEM keyword:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE email [
  <!ENTITY company SYSTEM "http://localhost/company.txt">
  <!ENTITY signature SYSTEM "file:///var/www/html/signature.txt">
]>

When the server parses this XML (e.g., in a SOAP API or web form), it fetches and substitutes the external resource. If the resolved value is returned in the response, an attacker referencing &signature; receives the contents of /var/www/html/signature.txt from the server’s filesystem.

This is the core mechanism behind XXE: external entity references that resolve to server-local files are returned to the attacker in the XML response.

Note: PUBLIC can be used instead of SYSTEM (typically for publicly declared standards), but SYSTEM covers most practical XXE cases.