Ultimate Sitemap Parser (USP): XML Entity Expansion (Billion Laughs) DoS in XMLSitemapParser
Date: 2026-06
Affected: pip/ultimate-sitemap-parser
Attack vector: dos
Category: vulnerability-disclosure
Severity: High
CWE: CWE-776
CVSS: 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

## XML Entity Expansion (Billion Laughs) DoS in XMLSitemapParser ### Summary `ultimate-sitemap-parser` version 1.8.0 and earlier parse attacker-controlled XML content using Python's `xml.parsers.expat` without any restriction on DTD declarations or recursive entity references. An attacker who can serve a malicious sitemap can trigger exponential XML entity expansion (the "Billion Laughs" attack), causing unbounded CPU and memory consumption in the victim process. No authentication, user interaction, or special configuration is required — the vulnerability is exploitable by default through any public-facing use of `sitemap_tree_for_homepage()` or `sitemap_from_str()`. ### Details The vulnerable code path begins at the public API entry points and flows to the Expat XML parser without any sanitization: 1. **`usp/tree.py:42`** — `sitemap_tree_for_homepage(homepage_url)` is the primary public entry point. 2. **`usp/tree.py:133`** — `sitemap_from_str(content)` is the secondary public entry point (also directly reachable from user code). 3. **`usp/fetch_parse.py:141-145`** — `SitemapFetcher._fetch()` retrieves the remote URL content. 4. **`usp/fetch_parse.py:175`** — The raw response becomes `response_content` (taint propagation point). 5. **`usp/fetch_parse.py:441-450`** — `XMLSitemapParser.sitemap()` creates an Expat parser and feeds the attacker-controlled content directly to it: ```python # usp/fetch_parse.py:441-450 — VULNERABLE SINK parser = xml.parsers.expat.ParserCrea


Mitigations:

Architectural layers (MAESTRO):