FastFeedParser has an infinite redirect loop DoS via meta-refresh chain
Date: 2026-04
Affected: pip/fastfeedparser
Attack vector: ssrf
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-39376
CWE: CWE-400
CWE-674
CVSS: 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

### Summary When `parse()` fetches a URL that returns an HTML page containing a `<meta http-equiv="refresh">` tag, it recursively calls itself with the redirect URL — with no depth limit, no visited-URL deduplication, and no redirect count cap. An attacker-controlled server that returns an infinite chain of HTML meta-refresh responses causes unbounded recursion, exhausting the Python call stack and crashing the process. This vulnerability can also be chained with the companion SSRF issue to reach internal network targets after bypassing the initial URL check. ### Details `parse()` catches `ValueError` on XML parse failure, extracts a meta-refresh URL from the HTML response via `_extract_meta_refresh_url()`, and tail-calls itself with that URL. The recursive call is unconditional — there is no maximum redirect depth, no set of already-visited URLs, and no guard against self-referential or looping redirects. **`fastfeedparser/main.py` — `parse()` (recursive sink):** ```python def parse(source: str | bytes, ...) -> FastFeedParserDict: is_url = isinstance(source, str) and source.startswith(("http://", "https://")) if is_url: content = _fetch_url_content(source) try: return _parse_content(content, ...) except ValueError as e: ... redirect_url = _extract_meta_refresh_url(content, source) if redirect_url is None: raise return parse(redirect_url, ...) # ← unconditional recursion, no depth limit ``` `_ex


Mitigations:

Architectural layers (MAESTRO):