Billion Laughs

Billion Laughs and Entity Expansion

The second family abuses internal entities: each entity refers to several copies of the previous one, so a document of a few hundred bytes expands to gigabytes ("billion laughs"), or one large entity is referenced many times (quadratic blowup). It is a denial-of-service attack on memory and CPU, and it needs no network access.

Modern parsers cap the expansion. In lxml vs ElementTree, Expat 1,381 (through Python 3.14) stopped with "limit on input amplification factor (from DTD and entities) breached" and libxml2 3,427 with "Maximum entity amplification factor exceeded". The JDK enforces entity-expansion limits when FEATURE_SECURE_PROCESSING is on, and defusedxml refuses the entity declarations before any expansion starts.

Entity-expansion defences by parser
Parser Built-in protection observed or documented Extra step
Expat 2.7 (Python stdlib) Amplification limit defusedxml for policy
libxml2 2.14-2.15 (lxml 3,063 , PHP) Amplification limit Keep huge_tree off
JDK (Xerces 129 ) Limits with secure processing Disallow DOCTYPE
.NET XmlReader DTDs prohibited by default Keep Prohibit

Limits are a safety net: also cap file sizes, parse with a timeout, and refuse DTDs the contract lacks.