CORS is not effective to restrict access

当你把 Gradio 应用挂载到 FastAPI 上,并用 FastAPI 的 CORSMiddleware 限制跨域来源时,Gradio 自带的 CORS 中间件会覆盖你的配置,导致 `Access-Control-Allow-Origin` 直接反射请求中的 `Origin` 头。优先排查你是否

快速结论:当你把 Gradio 应用挂载到 FastAPI 上,并用 FastAPI 的 CORSMiddleware 限制跨域来源时,Gradio 自带的 CORS 中间件会覆盖你的配置,导致 `Access-Control-Allow-Origin` 直接反射请求中的 `Origin` 头。优先排查你是否在非 localhost 的 Host 下访问应用,因为 Gradio 对 localhost 有额外的严格校验,会掩盖这个问题。

适用环境:Linux 操作系统;Gradio 5.7.1(Issue 报告版本),官方确认在 6.22.0(main 分支,commit `bf3b4e39c`)上仍可复现;依赖 FastAPI 与 uvicorn。

最快修复方案:暂无确认的一步修复方案。Issue 中建议把 `add_middleware(CORSMiddleware, …)` 放到 `gr.mount_gradio_app` 之后调用,但报告者实测无效。根源在于 Gradio 内部的 `CustomCORSMiddleware`(位于 `gradio/route_utils.py`)会先于用户配置的中间件执行,并把任何非 localhost 的 Origin 视为有效。

注意事项:该问题在 127.0.0.1 上不会暴露——Gradio 对 localhost 的严格校验会拦截所有跨域请求,从而掩盖回显行为。测试时需使用非 localhost 的 Host 头(例如通过 curl 自定义 Host 头)才能复现。官方已在修复 PR #13741 中提供修复后的 wheel 版本,但在你当前使用的 Gradio 版本上属于未验证方案,可优先尝试升级到修复后的版本。

问题场景

在 FastAPI 应用中通过 gr.mount_gradio_app 挂载 Gradio 应用,并为 FastAPI 添加 CORSMiddleware 限制 allow_origins。当使用 curl 或浏览器发送带有恶意 Origin 头的跨域请求时,Gradio 挂载的路由没有应用 FastAPI 的跨域限制,直接把请求的 Origin 反射到响应头的 Access-Control-Allow-Origin 中。而同样配置下的纯 FastAPI 路由则能正确生效,不返回该响应头。

报错原文

HTTP/1.1 200 OK
date: Thu, 02 Jan 2025 10:44:18 GMT
server: uvicorn
content-length: 4097
content-type: text/html; charset=utf-8
access-control-allow-credentials: true
access-control-allow-origin: https://malicious.com
vary: Origin

核心报错表现:响应中出现了 access-control-allow-origin: https://malicious.com,即任意 Origin 都被回显,未按 FastAPI 配置的 allow_origins=["https://example.com"] 进行限制。同时 access-control-allow-credentials: true 也被一并返回。

原因分析

可能原因:Gradio 内部自带了一个 CORS 中间件 CustomCORSMiddleware(位于 gradio/route_utils.py),它被 Gradio 在挂载时添加到应用中,且执行顺序在用户自行添加的 FastAPI CORSMiddleware 之外。该中间件的 is_valid_origin 逻辑为:

return (
    host_name not in self.localhost_aliases
    or origin_name in self.localhost_aliases
)

这意味着只要请求的 Host 不是 localhost,任何 Origin 都会被判定为有效,随后 allow_explicit_origin 会把传入的 Origin 原样反射到响应头,并附带 Access-Control-Allow-Credentials: true。由于 Gradio 的中间件运行在用户配置的 FastAPI CORSMiddleware 之外,用户的 allow_origins 列表对挂载的路由完全不生效。

Issue 中提到一种调整方案:将 add_middleware(CORSMiddleware, ...) 移到 gr.mount_gradio_app 之后调用,但报告者实测该方案仍然无效,因为 Gradio 的中间件依旧会覆盖响应头。

环境排查

  • 确认 Gradio 版本是否为 5.7.1 或 6.22.0(main 分支 commit bf3b4e39c 仍可复现);旧版本或新修复版本行为可能不同。
  • 确认应用是否通过非 localhost 的 Host 访问(例如 10.255.83.104 或通过 curl 自定义 Host 头);在 127.0.0.1 上 Gradio 的 localhost 严格校验会拒绝所有跨域请求,无法复现此问题。
  • 确认 FastAPI 的 CORSMiddleware 配置正确(allow_origins 是否正确设置),但需注意此配置并不影响 Gradio 挂载的路由。
  • 检查是否使用了官方修复 PR #13741 提供的 wheel 版本(可访问修复前后的 Hugging Face Space 对比:修复前 / 修复后)。

解决步骤

  1. (可优先尝试)确认官方已在 PR #13741 中修复此问题,并提供了修复后的 wheel 版本。尝试升级 Gradio 到该修复版本,验证 Access-Control-Allow-Origin 是否不再反射任意 Origin。
  2. 在升级前,调整中间件添加顺序:先执行 gr.mount_gradio_app,再调用 app.add_middleware(CORSMiddleware, ...)。注意:Issue 中报告者实测此方法仍无效,请以实测为准。
  3. 如无法升级且上述中间件顺序调整无效,考虑在更上层(如反向代理或 API 网关层)实施 CORS 策略,或在 Gradio 应用内自行拦截并修改响应头(需自行验证可行性)。
  4. 复现问题时可使用 curl 命令(Issue 中的原始复现命令):curl -i http://10.255.83.104:55800/ -H "Origin: https://malicious.com",或发送非 localhost 的 Host 头:curl -si http://127.0.0.1:7871/ -H "Host: app.internal:7871" -H "Origin: https://malicious.com"

验证方法

使用 curl 发送带有非允许 Origin 的请求(如 Origin: https://malicious.com),检查响应头中是否还包含 access-control-allow-origin: https://malicious.com。修复后应不再返回该响应头(或仅返回允许列表中的 Origin,如 https://example.com)。同时可访问官方提供的 修复后 Space 对比行为:仅在发送允许的 Origin 时才回显,恶意 Origin 不再被反射。

参考来源

gradio-app/gradio #10276

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 18306

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注