已合并
fix(http): restrict CORS to loopback origins and enforce Host header on loopback binds (closes #137) #460
xujing99创建于 7 天前
fix(http): restrict CORS to loopback origins and enforce Host header on loopback binds (closes #137) #460
已合并
xujing99创建于 7 天前
xujing99
xujing99成员
7 天前

当前PR是否有AI参与:

[x] 否

[ ] 是
__1. AI Agent 平台:
__2. AI 模型:
__3. Prompt上下文 :

参考:openEuler社区《生成式AI工具使用与开源贡献政策》

PR功能描述 / 为什么需要这个合入**:

1.1 修改目的

修复守护进程 HTTP API 对浏览器暴露过宽的安全缺陷:旧实现对任意网页都放行跨域访问且允许携带凭证,也拦不住 DNS 重绑定攻击(攻击者让自己的域名解析到 127.0.0.1,让浏览器误以为请求是同源的)。本次将浏览器可达性收紧到本机来源,并在本机监听时校验 Host 头,堵住远程网页读取/调用本机 API 的通道(修复 #137)。

1.2 关键变更点

  1. CORS 从“全放行”改为白名单:替换 CorsLayer::very_permissive(),只有本机来源(及显式配置的来源)能拿到跨域响应头。
  2. 永不启用带凭证的 CORS:API 走 Authorization 头鉴权而非 Cookie,凭证模式只会扩大暴露面。
  3. 新增 Host 头校验中间件:本机监听时,Host 不指向监听器的请求直接 403,挡住 DNS 重绑定。
  4. 新增 [http].allowed_origins 配置项:远程 Web UI 前置部署时可显式放行其来源,默认仅本机。
  5. Host 校验复用到 MCP 路由与 dashboard 监听:axum 后合并的路由不继承已有 layer,需单独包裹同一守卫。
  6. 同步更新配置 schema、用户文档与既有单测(补传默认安全策略参数)。

1.3 实现思路与机制原理

背景:守护进程的 HTTP API 会被浏览器直接调用——本地 Web UI 跑在另一个本机端口上。浏览器有个规则叫 CORS(跨域资源共享):网页要读别的来源的接口响应,必须由接口在响应里带上“允许该来源”的头。改动前用的是“超宽松”CORS(任意来源原样反射放行 + 允许凭证);而且 CORS 只管跨域请求,DNS 重绑定伪造出“同源”请求时它完全不生效,此时 Host 头是唯一能识别攻击的信号。

本次建立两道互补防线,配置收敛到新结构 HttpSecurityPolicy(监听地址 + 额外放行来源),随路由构造一路传递:

  1. CORS 白名单(router.rs 的 cors_layer/origin_is_allowed):每个请求的 Origin 先查配置的来源列表,再判断是否为 http/https 且主机是回环地址(localhost、127.0.0.0/8、::1,交给标准 IpAddr 解析以识别 0:0:0:0:0:0:0:1 等等价写法)。不命中则完全不返回 CORS 头,浏览器便拒绝把响应暴露给该网页。方法仅放行 GET/POST,请求头仅放行 Authorization/Content-Type。
  2. Host 校验(router.rs 的 enforce_loopback_host):仅当监听地址是回环地址且端口具体(非 0)时启用;请求 Host 按 RFC 3986 解析为 Authority,主机必须是回环名,带端口时必须等于监听端口,否则 403。这里没有手写 split(':'),并专门绕开了 Authority::port() 无法区分“无端口”与“端口畸形”(如 127.0.0.1:80x)的坑(authority_port_segment)。
  3. 防线覆盖全部监听面(main.rs):主 API 路由在构造时套上两层;MCP 路由是事后 merge 进来的、dashboard 是独立监听,axum 的 layer 不会自动覆盖它们,因此导出 apply_loopback_host_guard 对这两处单独包裹同一中间件。

设计取舍:Host 校验只在本机监听启用——非本机监听本来就必须配 bearer token 才能启动(既有检查 ensure_external_bind_is_authenticated),且常被反向代理前置,Host 不归守护进程管;本机来源免配置放行,因为远程网页伪造不出回环来源,能在本机起网页的进程本就能直连 API,那属于鉴权层的职责。

效果示例:

  • Origin: https://evil.com → 响应无任何 CORS 头,浏览器不暴露内容
  • Origin: http://localhost:3080(本地 UI)→ 正常反射放行
  • DNS 重绑定请求 Host: evil.example.com:8080(连接实际落在 127.0.0.1:8080)→ 403

1.4 影响范围/兼容性影响

  • 新增配置项 [http].allowed_origins(字符串数组,默认空 = 仅回环来源)。此前依赖“任意来源可跨域访问”的远程网页部署需显式配置,且应配合 bearer token(文档已提示)。
  • 本机监听(默认形态)下 Host 头必须指向监听器;正常浏览器/HTTP 客户端总会发送正确 Host,基本无感。
  • 非本机监听行为不变;路由构造函数签名新增 HttpSecurityPolicy 参数,仓内调用方与测试已同步。

该PR关联的issue

fixes #137

likedislike
Pull Request已成功合入, 合并人@openeuler-ci-bot
(感谢 xujing99 的贡献)
xujing99xujing99成员
7 天前 创建了 pull request,commit 1ad94d34
xujing99xujing99成员
7 天前 关联了issue:CorsLayer::very_permissive()(反射任意 Origin + allow_credentials)且无 Host 校验 ⇒ 任意网页可读写本地 daemon
openeuler-ci-botopeneuler-ci-bot成员
7 天前 将lyhu,huzhengce,liumiao27,zxstty,fromhsc,gogoxiaoxiao,wqianli,leon-wang2021,kaitiandu设为审查人
openeuler-ci-botopeneuler-ci-bot成员
7 天前 添加了label:sig/sig-intelligence
openeuler-ci-bot
openeuler-ci-bot成员
7 天前 评论:

Welcome To openEuler Community

Hey @xujing99 , thanks for your contribution to the community.

Bot Usage Manual

I'm the Bot here serving you. You can find the instructions on how to interact with me at Here . That means you can comment below every pull request or issue to trigger Bot Commands. You can self-configure the PR merge rules for this repository. For more details, please refer to Here.

Contact Guide

If you have any questions, please contact the SIG: sig-intelligence ,
and any of the maintainers: @fromhsc, @gogoxiaoxiao, @huzhengce, @kaitiandu, @leon-wang2021, @liumiao27, @lyhu, @wqianli, @zxstty ,
and any of the committers: @extinctfire, @hypothesiser, @xiangyou_xie, @xujing99 .

likedislike
openeuler-ci-botopeneuler-ci-bot成员
7 天前 添加了label:openeuler-cla/yes
openeuler-botopeneuler-bot成员
7 天前 添加了label:ci_processing
openeuler-bot
openeuler-bot成员
7 天前 评论:

门禁正在运行, 您可以通过以下链接查看实时门禁检查结果.
若您对门禁结果含义不清晰或者遇到问题不知如何解决,可参考门禁指导手册
门禁入口及编码规范检查: multiarch/openeuler/trigger/xiaoO/1024

likedislike
openeuler-botopeneuler-bot成员
7 天前 删除了label:ci_processing
openeuler-bot
openeuler-bot成员
7 天前 评论:
Check Name Build Result 详情 Build Details
check_package_license ⚠WARNING • 仓库copyright检查未通过: 缺少项目级Copyright声明文件 #1024
check_sca ✅SUCCESS
check_ci ⚠WARNING • CI脚本检查未通过,请查看Build Details
x86_64 check_build ✅SUCCESS #1047
aarch64 check_build ✅SUCCESS #1029
likedislike
openeuler-botopeneuler-bot成员
7 天前 添加了label:ci_successful
openeuler-bot
openeuler-bot成员
7 天前 评论:
likedislike
xujing99xujing99成员
7 天前 预合并成功(commit_id: 9486abd55e00d02ef12cdf5c633a472759c4aa50)
xujing99xujing99成员
7 天前 强制推送  1 个提交:817d9653-fix(http): restrict CORS to loopback origins and enforce Host header on loopback binds (closes #137)
xujing99xujing99成员
7 天前 预合并成功(commit_id: ed0aed907da62ca7571b2ac196a84dbc25e93722)
openeuler-ci-botopeneuler-ci-bot成员
7 天前 删除了label:openeuler-cla/yes
openeuler-ci-botopeneuler-ci-bot成员
7 天前 删除了label:ci_successful
openeuler-ci-bot
openeuler-ci-bot成员
7 天前 评论:

Notification

This pull request has been changed(code update) or closed, so removes the following label(s): ci_successful.

likedislike
openeuler-ci-botopeneuler-ci-bot成员
7 天前 添加了label:openeuler-cla/yes
openeuler-ci-bot
openeuler-ci-bot成员
7 天前 评论:

CLA Signature Pass

xujing99, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
openeuler-botopeneuler-bot成员
7 天前 添加了label:ci_processing
openeuler-bot
openeuler-bot成员
7 天前 评论:

门禁正在运行, 您可以通过以下链接查看实时门禁检查结果.
若您对门禁结果含义不清晰或者遇到问题不知如何解决,可参考门禁指导手册
门禁入口及编码规范检查: multiarch/openeuler/trigger/xiaoO/1026

likedislike
openeuler-botopeneuler-bot成员
7 天前 删除了label:ci_processing
openeuler-bot
openeuler-bot成员
7 天前 评论:
Check Name Build Result 详情 Build Details
check_package_license ⚠WARNING • 仓库copyright检查未通过: 缺少项目级Copyright声明文件 #1026
check_sca ✅SUCCESS
check_ci ✅SUCCESS
x86_64 check_build ✅SUCCESS #1049
aarch64 check_build ✅SUCCESS #1031
likedislike
openeuler-botopeneuler-bot成员
7 天前 添加了label:ci_successful
openeuler-bot
openeuler-bot成员
7 天前 评论:
likedislike
xujing99xujing99成员
7 天前 修改了pull request 的描述
hypothesiser
hypothesiser成员
7 天前 评论:

/lgtm

likedislike
hypothesiser
hypothesiser成员
7 天前 评论:

/approve

likedislike
openeuler-ci-botopeneuler-ci-bot成员
7 天前 添加了label:lgtm
openeuler-ci-bot
openeuler-ci-bot成员
7 天前 评论:

Review Code Feedback

  • The label lgtm was added to this pull request. It means that hypothesiser reviewed the code changes. 👋
Tips
  • If this pull request is not merged while all conditions are met, comment /check-pr to try again. 😄
likedislike
openeuler-ci-botopeneuler-ci-bot成员
7 天前 添加了label:approved
openeuler-ci-bot
openeuler-ci-bot成员
7 天前 评论:

Review Code Feedback

  • The label approved was added to this pull request. It means that hypothesiser reviewed the code changes. 👋
Tips
  • If this pull request is not merged while all conditions are met, comment /check-pr to try again. 😄
likedislike
openeuler-ci-botopeneuler-ci-bot成员
7 天前 合入了pull request,合并节点 SHA:331a43916e40aafd37e7b0a1bb7eb4c02aecb307
openeuler-ci-bot
openeuler-ci-bot成员
7 天前 评论:

PR Merge Failed

  • reason: {"message":"Pull Request 已合并或已关闭。"}
likedislike