核心要点
SSRF 是 MCP 工具调用的天然攻击面:MCP Server 的 HTTP 工具端点把用户可控 URL 交给服务端请求,模型被诱导调用时即可触发(CWE-918),攻击者可扫描内网、访问云元数据
鉴权不消除 SSRF:CVE-2026-39974 是 n8n-MCP 多租户 HTTP 模式下的 authenticated SSRF(CVSS 8.5),合法登录用户仍可借服务端身份访问内网资源
安全函数存在不等于被调用:CVE-2026-34163 中 FastGPT 已有 isInternalAddress(),但 MCP 工具端点没调用它,攻击者可扫描内网并访问 MongoDB/Redis
防御必须分层:URL 协议/IP 校验 + 解析后复查防 DNS rebinding、沙箱 egress 白名单兜底、云元数据 169.254.169.254 显式封禁、最小权限与审计告警
标准回答
一、先识别 MCP 场景下的 SSRF 攻击面
MCP 把外部工具标准化接入 Agent,最常见的工具类型就是「给一个 URL,由服务端去抓取或调用」。当工具端点的 URL 参数由用户或模型可控时,服务端就带着自己的网络位置和凭据去访问目标——这正是 SSRF(服务端请求伪造) 的定义,对应 CWE-918。Agent 场景还叠加了放大链路:攻击者不一定直接控制 URL,而是通过 prompt injection 诱导模型调用 URL 工具,让模型替攻击者构造请求,再借服务端身份访问内网、云元数据或受限资源。
二、两个 2026 年 CVE 的工程教训
CVE-2026-39974(n8n-MCP,CVSS 8.5):多租户 HTTP 模式下经 instance-URL header 触发的 authenticated SSRF,2.47.4 修复。关键教训是鉴权只证明「你是谁」,不证明「你该访问哪里」——合法登录用户仍可让服务端去请求内网目标。CVE-2026-34163(FastGPT,CVSS 7.7):MCP 工具端点(getTools/runTool)接受用户提供的 URL 并发起服务端请求,却没有调用项目里已有的 isInternalAddress() 校验函数,攻击者可扫描内网并访问 MongoDB/Redis。这个案例说明安全函数存在不等于被每个端点调用,防护必须做成强制网关而非靠开发者自觉。
三、应用层与网络层防御纵深
应用层:只允许 http/https 协议;解析 URL 后对目标 IP 做私网/回环/链路本地段校验(127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、169.254.169.254 云元数据段、IPv6 等价段);不能只查字符串,要解析 DNS 后在连接前复查真实 IP,并固定解析结果,否则可用十进制 IP、短域名、DNS rebinding 绕过;重定向要限制跳转次数并重新校验。网络层:MCP Server 放进受限沙箱,egress 只放行白名单域名/端口,即使应用层校验被绕过,请求也到不了内网。
四、最小权限与审计闭环
给每个工具声明最小权限:URL 类工具只允许访问业务必需域名,用 allowlist 而非 denylist;高危工具(读文件、执行命令、内网访问)走 human-in-the-loop;把工具返回值当不可信数据,防止二次注入放大;对工具调用记录目标 URL、解析 IP、结果与耗时,接入异常监控——出现访问内网段或云元数据地址的请求立即告警。修复 CVE 后还应按「内网信息可能已被探测」的假设做凭据轮换与日志审查。
常见误区
⚠️ 常见踩坑
误区一:以为做了鉴权就安全。 CVE-2026-39974 恰恰是 authenticated SSRF——认证只能证明调用方是合法用户,不能证明服务端应该访问哪个目标;SSRF 的受害者是服务端所在网络,而不是调用方。误区二:以为封了 localhost 就够。 内网还包括 10/172.16/192.168 段、云元数据 169.254.169.254、IPv6 映射地址;攻击者还能用 DNS rebinding 把域名先解析到公网再切到内网,字符串黑名单拦不住。误区三:以为安全函数写在代码里就生效。 CVE-2026-34163 说明校验函数没被新端点调用等于没有,防护要收敛到统一网关层强制执行。误区四:只做应用层校验,忽略网络出口。 纵深防御的最后一道防线是沙箱 egress 白名单,否则应用层一旦被绕过就直通内网。
追问
追问 1:DNS rebinding 为什么能绕过 URL/IP 校验?如何防御?
绕过原理:攻击者注册一个域名,第一次解析返回公网 IP(通过校验),请求方校验通过后,攻击者立刻把 DNS 记录改成内网 IP(如 192.168.1.1);服务端连接时重新解析,就拿到了内网地址。浏览器和 HTTP 客户端默认会做多次解析,给了 rebinding 窗口。防御方法:解析后固定 IP 再连接(pin 解析结果),即「解析一次、校验、用同一 IP 发起连接」;对解析出的所有 A/AAAA 记录逐一校验,任一命中私网段就拒绝;更彻底的做法是服务端只接受 IP 直连白名单或域名白名单并在 DNS 层做 ECS 固定,同时用 egress 白名单兜底——即使应用层被绕过,网络层也放行不到内网。
追问 2:如果业务确实需要 MCP 工具访问内网服务,如何安全放行?
用显式 allowlist 而非开放内网:把允许访问的内网服务登记成「域名 + 端口 + 路径」白名单,在网关层做目标匹配,未命中直接拒绝;为不同租户或 Agent 划分独立网络命名空间,内网服务按最小必要范围暴露(如只开放业务端口,禁止管理端口与云元数据地址)。云元数据 169.254.169.254 永远不进白名单,需要元数据时由平台侧注入短期凭证而不是让工具直接访问。高危内网访问要求 human-in-the-loop 或二次审批,并记录完整审计日志——2026 年 FastGPT 案例的教训就是工具端点绕过了已有校验,放行逻辑必须与业务代码解耦、统一在代理层强制执行。
追问 3:MCP 场景的 SSRF 与普通 Web 应用的 SSRF 有什么本质区别?
区别在攻击入口和放大能力。普通 Web SSRF 的攻击者是外部请求方,直接构造含内网地址的 URL;MCP 场景里模型是中间层——攻击者通过 prompt injection 或工具投毒让模型主动调用 URL 工具,甚至把工具返回值里的链接再次交给模型,形成二次 SSRF 链。这意味着:第一,防护不能假设「模型只会调我允许的工具」,工具参数必须在运行时强制校验;第二,MCP Server 常部署在能访问源码仓库、云凭据、CI 环境的位置,爆炸半径比普通 Web 应用更大;第三,除了 URL 类工具,文件读取、命令执行类工具同样要按最小权限收紧。防御本质不变——纵深防御 + 最小权限 + 审计,但要围绕「模型也是攻击入口」重新设计信任边界。
🔗 相似问题
同一考点的不同问法,换着练更稳
延伸学习
按主题分类的相关资源,便于系统复习
