XML Entity Expansion Limits and DoS Prevention
This article explores what an XML entity expansion limit is, how recursive entity expansion creates devastating XML bomb attacks, and the mechanisms by which enforcing expansion limits prevents Denial of Service (DoS) conditions. By capping the cumulative size and recursion depth of entity replacements during parsing, systems can safely process XML documents without risking CPU and memory exhaustion.
The Risk: XML Entity Expansion and XML Bombs
Extensible Markup Language (XML) supports the definition of custom entities inside a Document Type Definition (DTD). When an XML parser encounters an entity reference, it replaces the reference with the defined value.
While useful for templating and text reuse, this feature can be weaponized through recursive or nested entity definitions, commonly known as an “XML bomb” or the “Billion Laughs” attack. In this scenario, a small XML file (often less than one kilobyte) defines a chain of entities where each entity references multiple instances of a preceding entity.
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
]>
<lolz>&lol3;</lolz>When the parser attempts to resolve &lol3;, it
expands exponentially in memory. An attack payload can easily expand
into gigabytes of data, rapidly consuming all available system memory
(RAM) and CPU cycles. This resource exhaustion leads to application
crashes, server unresponsiveness, and a complete Denial of Service for
legitimate users.
What Is an XML Entity Expansion Limit?
An XML entity expansion limit is a parser-level security configuration that restricts the number of times entities can be recursively expanded or caps the total number of characters generated by entity replacement.
Instead of allowing an entity to expand indefinitely until memory is exhausted, the parser maintains an internal counter during the processing of the document. If the expansion count or the resulting payload size crosses a predefined numerical threshold, the parser immediately halts processing and throws a parsing exception.
Key components governed by expansion limits include: - Total Entity Expansion Count: The absolute number of times any entity replacement can occur within a single document. - Entity Expansion Depth: The maximum level of nested or recursive entity definitions allowed. - Node Count and Max Entity Size: Limits on the total number of nodes generated or the maximum character size allowed for a single entity value.
How the Limit Prevents Denial of Service
Enforcing an entity expansion limit mitigates DoS threats through several key mechanisms:
1. Deterministic Resource Bound
By setting a strict ceiling on entity expansions, administrators enforce an upper bound on memory allocation and CPU processing time per request. The parser guarantees that parsing a payload will not consume more than a predictable, safe amount of memory.
2. Early Failure Detection
When an attacker sends a malicious recursive payload, the expansion counter hits the limit almost instantly—long before significant memory is allocated or CPU cycles are wasted. The parser rejects the malformed input at the earliest stage of processing.
3. Protection Against Quadratic Blowup
In addition to recursive attacks, limits protect against “Quadratic Blowup” attacks, where an attacker defines a massive entity once and references it thousands of times without recursion. Entity limits track cumulative expansions across the entire document, neutralizing this variation as well.
Implementation Best Practices
To secure XML parsers against DoS attacks via entity expansion:
- Disable DTDs Entirely: If external DTDs or general
entity definitions are not required by your application, disable DTD
processing completely (e.g., using
disallow-doctype-declin Java orloadDTD = falsein other runtimes). - Configure Secure Processing: In environments like
Java, enable
XMLConstants.FEATURE_SECURE_PROCESSING(FSP), which applies sensible default limits to entity expansions and entity sizes. - Set Explicit System Properties: Explicitly
configure parser limits (such as
jdk.xml.entityExpansionLimitin Java orXML_PARSE_HUGEflags in libxml2) to values appropriate for your application’s expected workloads.