XML Entity Expansion (Billion Laughs / XXE)
Also Known As
billion laughs attack
XML bomb
exponential entity expansion
TL;DR
Denial-of-service via exponentially nested XML entities (Billion Laughs) or SSRF/file-read via external entity references (XXE).
Explanation
Two related XML attacks: the Billion Laughs DoS defines nested entities that expand exponentially (lol1 = 10×lol0, lol2 = 10×lol1 ... lol9 = billions of characters), exhausting server memory parsing a tiny document. XXE (XML External Entity) uses <!ENTITY ext SYSTEM 'file:///etc/passwd'> to read local files or <!ENTITY ext SYSTEM 'http://internal/'> to trigger SSRF. PHP's libxml is vulnerable by default. Mitigations: call libxml_disable_entity_loader(true) (PHP < 8.0) or use LIBXML_NONET | LIBXML_NOENT flags with simplexml_load_string() / DOMDocument::loadXML(). In PHP 8.0+ external entity loading is disabled by default. Never parse untrusted XML with a SAX/DOM parser that hasn't had entity expansion disabled.
Common Misconception
✗ XML entity expansion is only a theoretical DoS risk. A crafted document with nested entity references can expand to gigabytes in memory from kilobytes of input, crashing a server in milliseconds. Always disable entity expansion when parsing untrusted XML.
Why It Matters
The billion laughs attack uses nested entity references to expand a small XML document to gigabytes, exhausting memory and crashing the parser — one request, full DoS.
Common Mistakes
- Parsing user-supplied XML without setting LIBXML_NOENT to disable entity expansion.
- Using SimpleXML or DOMDocument on untrusted input without calling libxml_disable_entity_loader(true) first.
- Not setting resource limits (memory, CPU time) for XML parsing operations.
- Assuming entity attacks only apply to XXE — expansion attacks do not require external entity loading.
Avoid When
- Never parse user-supplied XML with unlimited entity expansion enabled — a single crafted document can exhaust server memory.
- Do not use DOMDocument or SimpleXML on untrusted input without configuring safe parse options first.
When To Use
- Disable entity expansion when parsing untrusted XML using LIBXML_NOENT awareness and libxml_disable_entity_loader().
- Set a maximum entity expansion depth/count limit when processing XML from external sources.
Code Examples
✗ Vulnerable
$xml = simplexml_load_string($untrusted); // XXE possible pre-PHP 8
✓ Fixed
libxml_disable_entity_loader(true); // PHP < 8.0
$xml = simplexml_load_string($untrusted, 'SimpleXMLElement', LIBXML_NOENT | LIBXML_NONET);
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
31 Mar 2026
Views
18
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Amazonbot 7
Perplexity 2
Unknown AI 2
ChatGPT 2
Ahrefs 1
Google 1
Also referenced
How they use it
crawler 13
crawler_json 2
Related categories
⚡
DEV INTEL
Tools & Severity
🔴 Critical
⚙ Fix effort: Low
⚡ Quick Fix
Set LIBXML_NONET when parsing XML and configure libxml_disable_entity_loader(true) for PHP < 8.0 — Billion Laughs attack uses nested entity expansion to exhaust memory with a tiny XML file
📦 Applies To
PHP 5.0+
web
api
cli
🔗 Prerequisites
🔍 Detection Hints
XML parsing without entity expansion limits; LIBXML_NOENT not disabled; simplexml_load_string without entity restrictions
Auto-detectable:
✓ Yes
semgrep
psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Low
✓ Auto-fixable
Fix: Low
Context: Line
CWE-776
CWE-400