ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

OpenMuse 浏览器网络边界剖析:用回环代理与 DNS 校验彻底防住 SSRF 攻击

OpenMuse 浏览器网络边界剖析:用回环代理与 DNS 校验彻底防住 SSRF 攻击 OpenMuse 浏览器网络边界剖析用回环代理与 DNS 校验彻底防住 SSRF 攻击【免费下载链接】openmuseA personal agent with a browser, terminal, files, and work that keeps going built with CopilotKit and AG-UI.项目地址: https://gitcode.com/gh_mirrors/op/openmuseOpenMuse 是一个内置浏览器、终端与文件能力的个人 AI Agent基于 CopilotKit 与 AG-UI 构建。当 AI 替你上网时它可能成为攻击者探测你内网、云元数据接口的跳板——这正是经典的SSRF服务端请求伪造风险。本文将带你完整剖析 OpenMuse 浏览器 Worker 如何用「DNS 校验 回环出口代理」双层机制把 SSRF 攻击彻底挡在公网边界之外。先认识一下攻击场景攻击者诱导 Agent 访问http://127.0.0.1:8080/admin或http://169.254.169.254/云厂商元数据接口浏览器就会带着内网身份去请求敏感服务。更狡猾的是DNS 重绑定——域名第一次解析到公网 IP 骗过检查第二次解析到内网 IP 完成攻击。一、三道防线总览OpenMuse 浏览器网络边界OpenMuse 的浏览器能力由独立的 Node/Playwright Worker 承担apps/worker/它对出站流量执行「应用层强制出口策略」共三层检查DNS 校验解析域名后检查每一个 IP 是否为公网地址任一答案指向私有网段即整体拒绝回环出口代理所有流量必须经过绑定在127.0.0.1的代理代理直接连接校验过的那个 IP杜绝二次解析重绑定浏览器强制走代理Chromium 被配置为禁用 QUIC、屏蔽绕过回环、关闭非代理 WebRTC UDP并拦截 WebSocket 与 Service Worker。官方边界说明见 apps/worker/README.md 的 Network boundary 章节部署边界见 SECURITY.md。二、第一道防线DNS 校验与公网 IP 白名单核心函数validatePublicUrl位于 apps/worker/src/network.ts。它对每个目标 URL 执行以下检查协议与端口只允许http:/https:且端口必须是 80 或 443禁止 URL 中携带用户名密码域名黑名单localhost、*.local、*.internal、*.home、*.lan等内网风格域名直接被拒DNS 解析带 5 秒超时解析失败返回DNS_UNAVAILABLE而不是放行逐答案校验调用isPublicIp检查所有解析出的地址任何一个落入私有/保留网段就整体拒绝。isPublicIp的白名单逻辑network.ts覆盖了几乎所有「不该去」的地址空间IPv4 的10/8、172.16/12、192.168/16、回环127/8、链路本地169.254/16、CGNAT100.64/10、多播与保留段IPv6 也只放行2000::/3中真正的全局单播范围排除文档段、测试段和 ULA。 关键设计不是「主记录是公网就放行」而是任一答案不合法即整条拒绝。这直接封堵了「一公网一内网双记录」的绕过手法。三、第二道防线回环出口代理连接固定 IP 防 DNS 重绑定即便 DNS 校验通过攻击者仍可能在「校验完」和「浏览器真正连接」之间的时间窗里换掉解析结果DNS 重绑定。OpenMuse 的解法是一个只绑定回环地址的出口代理apps/worker/src/proxy.ts代理监听在127.0.0.1的随机端口外网无法直连它每个请求再次调用validatePublicUrl拿到校验后的 IP 后用该 IP 直连上游注释明确写着「All upstream sockets connect to a validated IP, never a second DNS lookup」——即永远不会发生第二次 DNS 解析非法目标返回403 Destination blockedHTTPS 隧道CONNECT只接受 443 端口并做同样的 IP 校验上游请求 30 秒超时隧道 60 秒空闲超时避免连接被长期占用。这样「校验的 IP」和「实际连接的 IP」是同一个重绑定窗口被彻底关闭。四、第三道防线让浏览器无法绕开代理校验再严也要保证 Chromium 真的走代理。会话创建逻辑apps/worker/src/browser.ts做了四件事代理配置proxy: { server: proxy.url, bypass: -loopback }——显式移除 Playwright 默认的「回环地址绕过代理」防止浏览器对127.0.0.1走直连启动参数--disable-quicQUIC 是 UDP不走 HTTP 代理、--force-webrtc-ip-handling-policydisable_non_proxied_udp关 WebRTC UDP 泄露、--host-resolver-rulesMAP * ~NOTFOUND, EXCLUDE 127.0.0.1让浏览器自身 DNS 失效除回环代理外无处可查路由级二次拦截对页面所有子请求挂context.route逐个再跑一遍validatePublicUrl不合法直接abortWebSocket 一律关闭Service Worker 被禁用跳转后复验页面跳转含 Playwright 路由钩子之外的重定向完成后navigate会对最终 URL再次执行validatePublicUrlbrowser.ts失败则回退到about:blank并上报NAVIGATION_FAILED绝不把被拦截的目标谎报为加载成功。此外worker API 本身只接受可信服务端携带的WORKER_TOKEN调用apps/worker/README.md浏览器与移动端客户端永远拿不到该令牌从入口侧缩小了攻击面。五、如何验证这套防护现成的自动化测试无需真机环境即可快速回归核心 SSRF 防护tests/browser.test.tspnpm exec tsx --test tests/browser.test.ts其中「egress proxy blocks HTTP and CONNECT traffic to local network destinations」用例会向回环代理发起指向127.0.0.1的 GET 与 CONNECT 请求断言两者都返回403。若要跑真实 Chromium 容器化验证含认证、导航、下载、重启与 profile 持久化执行node apps/worker/tests/run-docker.mjsapps/worker/README.md 的 Verify 章节。六、边界意识它不是内核防火墙OpenMuse 在文档中非常坦诚地标注了这条防线的性质apps/worker/README.md、SECURITY.md这是应用层强制出口策略不是内核级网络隔离也不承诺防御 Chromium 0day 漏洞本身作为纵深防御Docker 镜像以非 root 用户pwuser运行apps/worker/Dockerfile无 Docker socket、无模型密钥、只读根文件系统、内存/进程受限多租户强隔离部署时官方建议参考 Playwright 的容器化指南另行加固。七、总结清单防线位置拦截什么DNS 校验 公网 IP 白名单network.ts私有/保留网段、内网域名、非 80/443 端口回环出口代理固定 IP 直连proxy.tsDNS 重绑定、代理绕过浏览器强制代理 路由复验browser.ts直连回环、QUIC/WebRTC 泄露、跳转后逃逸OpenMuse 的这套设计给出了一个很好的教科书式答案校验过的地址必须就是实际连接的地址。如果你要为任何「AI 上网」类项目做安全评审把这三层逐条对照检查就基本能守住 SSRF 这条最常见的攻击路径。【免费下载链接】openmuseA personal agent with a browser, terminal, files, and work that keeps going built with CopilotKit and AG-UI.项目地址: https://gitcode.com/gh_mirrors/op/openmuse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表