漏洞本质:Host 头如何成为攻击向量
CVE-2026-48710(BadHost)揭示了 Python ASGI 生态中一个隐蔽但影响广泛的认证绕过路径。该漏洞的核心在于 Starlette 框架(< 1.0.1)构建 request.url 的方式:它将 HTTP Host 头与请求路径直接拼接,生成完整的 URL 对象。当攻击者在 Host 头中注入额外路径或查询参数时,request.url.path 返回的值将与实际请求路径不一致,导致基于路径的认证中间件做出错误的安全决策。
典型的攻击场景如下:攻击者向受保护的 /admin 端点发送请求,但将 Host 头设置为 example.com/health?x=。此时 ASGI 服务器将请求路由至 /admin,但 Starlette 构造的 request.url 变为 https://example.com/health?x=/admin,request.url.path 返回的是 /health 而非真实的 /admin。如果中间件配置为允许 /health 路径免认证访问,攻击者便成功绕过了 /admin 的保护机制。
技术成因:三层组件的信任链断裂
这一漏洞的形成涉及 HTTP 协议、ASGI 规范和 Starlette 框架三个层面的交互。ASGI 服务器(如 Uvicorn、Hypercorn)负责解析 HTTP 请求并将原始 Host 头传递给应用层,按照规范它不会对 Host 头进行语义验证。Starlette 的 URL 类在初始化时,将 Host 头与路径拼接构建完整 URL,这一设计假设 Host 头仅包含主机名和端口。然而,HTTP 规范并未禁止 Host 头包含路径字符,攻击者可以利用这一差异注入恶意内容。
问题的关键在于认证中间件的实现模式。许多开发者习惯在 BaseHTTPMiddleware 或自定义 ASGI 中间件中使用 request.url.path 来判断是否跳过认证检查,例如实现白名单或黑名单机制。这种 "路径级认证" 模式与 Starlette 的 URL 构建机制结合后,产生了可被利用的安全缺口。值得注意的是,FastAPI 内置的 Depends() 和 Security() 机制使用路由匹配而非 request.url.path,因此标准的安全依赖注入不受此漏洞影响。
影响范围:AI 基础设施的高风险暴露
漏洞的影响远超传统 Web 应用。当前大量 AI/ML 基础设施构建于 FastAPI/Starlette 之上,包括 vLLM(LLM 推理服务器)、LiteLLM(LLM 代理服务)、MCP(Model Context Protocol)服务器以及各类 AI Agent 框架。这些系统常使用路径级中间件来保护模型访问端点、API 密钥管理接口和内部工具链。
MCP 服务器尤其值得关注。根据 MCP 规范,OAuth 发现端点必须保持未认证状态以支持协议握手,这为攻击者提供了可靠的利用路径 —— 通过 Host 头注入将受保护端点伪装成 OAuth 发现端点,即可绕过认证。Google ADK-Python、Ray Serve 和 BentoML 等框架在添加自定义认证中间件时同样面临风险。据 X41 D-Sec 的评估,GitHub 上依赖 Starlette 的项目超过 40 万个,实际暴露面取决于各项目中间件的实现方式。
防御加固:四层修复策略
针对此漏洞,建议从框架升级、架构设计、基础设施和代码实践四个层面实施防护。
框架升级:最直接的修复是将 Starlette 升级至 1.0.1 或更高版本。该版本会忽略包含非法字符的 Host 头,不再将其用于 URL 构造。对于使用 FastAPI 的项目,需确保底层 Starlette 依赖已更新。
架构调整:避免在路径级中间件中实施认证决策。认证逻辑应绑定到具体端点而非路径字符串。Starlette 提供 requires() 装饰器,FastAPI 提供 Depends() 和 Security() 依赖注入机制,这些方式基于路由匹配而非 request.url.path,天然免疫此类攻击。
反向代理部署:在 ASGI 服务器前部署 RFC 合规的反向代理(nginx、Caddy、Traefik、HAProxy)可有效缓解风险。这些代理会对 Host 头进行验证和规范化,拦截包含路径或查询参数的非法值。建议生产环境始终采用此架构,开发 / 测试环境亦应遵循。
代码层修复:如必须在中间件中处理路径,使用 ASGI scope 中的 scope["path"] 替代 request.url.path。前者取自 HTTP 请求行,不受 Host 头内容影响。审查现有代码中所有使用 request.url.path 的中间件,评估其安全影响。
检测与自查:静态扫描与动态验证
X41 D-Sec 已开源完整的检测工具链。静态分析方面,可使用 Semgrep 规则扫描代码库中 request.url.path 在中间件中的使用,或使用 CodeQL 进行大规模仓库扫描。动态验证方面,badhost.org 提供在线扫描器,支持 MCP 服务器、AI 基础设施和自定义路径三种检测模式。扫描器采用原始 TCP 套接字发送请求,绕过标准 HTTP 客户端对 Host 头的规范化处理,能够准确检测 denylist(失败开放)和 allowlist(失败关闭)两种中间件模式。
自查时应重点关注:自定义 BaseHTTPMiddleware 实现、ASGI 中间件中的路径白名单 / 黑名单逻辑、以及任何基于 request.url 属性做出的安全决策。对于 AI 基础设施,还需检查 MCP 端点的认证配置是否符合规范要求。
总结
CVE-2026-48710 揭示了现代 Web 框架中 "组合式漏洞" 的典型特征:单个组件(ASGI 服务器、Starlette、中间件)在隔离状态下行为正确,但交互时产生安全缺口。对于运行 AI 服务的团队而言,这一漏洞提醒我们关注底层框架的安全更新,审视认证架构的合理性,并在基础设施层面建立纵深防御。
资料来源
- X41 D-Sec 安全公告 X41-2026-002: https://x41-dsec.de/lab/advisories/x41-2026-002-starlette/
- GitHub Security Advisory GHSA-86qp-5c8j-p5mr: https://github.com/Kludex/starlette/security/advisories/GHSA-86qp-5c8j-p5mr
- BadHost 漏洞扫描与说明: https://badhost.org/
内容声明:本文无广告投放、无付费植入。
如有事实性问题,欢迎发送勘误至 i@hotdrydog.com。