🔐 为什么 SSRF 总能打到云主机的“内脏”

很多人第一次接触 SSRF(Server-Side Request Forgery,服务端请求伪造)时,会把它理解成“让服务器替我发一个请求”。这句话没错,但太轻了,真正危险的地方在于:服务器看到的网络世界,和普通用户看到的不是一回事。你的浏览器访问不到 127.0.0.1、内网地址、云平台元数据服务,但业务服务器往往可以。于是一个看起来只是“帮你抓取图片 URL”“读取 webhook 地址”“预览远程文件”的功能,只要把用户提供的地址直接交给后端去请求,就可能变成一把通向内网的钥匙。

为什么这事总发生?因为开发者脑子里想的是“这是个 URL 字符串”,攻击者脑子里想的是“这是一次由高权限网络位置发起的连接”。一旦后端没有严格限制目标地址,攻击者就会把请求打向本地服务、Redis、管理面板,或者云环境里最经典的目标:metadata service。比如在 AWS 里,169.254.169.254 这个地址可能暴露实例身份凭证;一旦拿到临时 Access Key,问题就不再是“读到一段数据”,而是横向访问对象存储、消息队列,甚至整个云账号里的其他资源。

现实防护的关键,不是写一堆黑名单字符串匹配,因为那很容易被绕过。你拦 127.0.0.1,别人就用十进制、八进制、IPv6、DNS 解析跳转,或者先指向外部域名再让它解析到内网。真正靠谱的做法是把“服务器能主动连谁”变成默认拒绝,只允许业务明确需要的目标。也就是说,先做 egress allowlist,再做 URL 解析后的真实地址校验,校验的是最终 IP,不是用户输入的那串文本。同时,云上一定要关心 metadata 的保护机制,比如 AWS IMDSv2,不要让实例凭证裸奔;应用层面则尽量别让后端去请求用户任意给的 URL,如果业务上非做不可,就把它扔进隔离网络和低权限容器里跑。

🧪 题目:某文件预览服务支持用户输入一个链接,后端会下载内容并生成缩略图。开发者已经拦截了字符串里出现 127.0.0.1localhost169.254.169.254 的情况,于是觉得 SSRF 风险已经解决。这个判断对吗?为什么?答案:

💡 核心记忆:SSRF 的本质不是“输入了恶意 URL”,而是“你让服务器替攻击者站在更高权限的位置看网络”。
#Security