🔐 为什么 SSRF 总能打到云主机元数据服务

很多人第一次学 SSRF(Server-Side Request Forgery,服务端请求伪造)时,会把它理解成“让服务器替你访问一个 URL”。这句话没错,但太轻了。真正危险的地方在于:服务器看到的网络世界,和外部用户看到的根本不是一回事。你在浏览器里访问不到 127.0.0.1、169.254.169.254、内网 Redis、Kubernetes API,但应用服务器自己往往能访问,因为这些地址本来就是给“机器自己”用的。

云环境里最经典的目标就是元数据服务(metadata service)。以 AWS 为例,老版本 IMDSv1 会在 169.254.169.254 这个链路本地地址上提供实例身份信息,甚至临时凭证。开发者本来是想让自己写的程序方便拿到 IAM Role 凭证,于是把这扇门开在机器旁边。问题在于,只要你的应用里有“帮用户取 URL 内容”“抓取图片”“网页预览”“导入远程文件”这种功能,而又没有严格限制目标地址,攻击者就能把这个功能拐弯用到元数据服务上。表面上是应用在请求,实际上是攻击者借你的服务器拿钥匙。

这就是为什么现实里的 SSRF 经常不是直接打外网,而是先摸内网,再拿凭证,再横向移动。你以为只是一个读网页的小功能,最后可能变成云账号权限泄露。很多事故不是因为密码太弱,而是因为服务器被允许替别人访问了它本不该访问的地方。

防 SSRF 也别搞成一堆漂亮口号,核心就几件事。第一,不要做“任意 URL 获取器”,最好改成白名单目标,只允许访问明确批准的域名和协议。第二,解析 URL 不能只看字符串,要在 DNS 解析后校验最终 IP,拦住 127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、169.254.0.0/16 这些本地和内网地址,不然别人会用域名跳转、DNS Rebinding、整数 IP、IPv6 映射这些花样绕过去。第三,从网络层限制出站访问,比在业务代码里堆 if 靠谱得多。第四,在云上直接关掉高风险入口,比如 AWS 优先使用 IMDSv2,它要求先拿 token,再访问元数据,能挡掉一批最粗暴的 SSRF 利用链。

🧪 某团队做了一个“上传头像 by URL”的功能,后端会下载用户给的图片链接并保存。开发者已经禁止了 URL 中出现 169.254.169.254 这个字符串,于是觉得元数据服务安全了。攻击者改用一个自己控制的域名,DNS 解析结果指向 169.254.169.254。这个防护还挡得住吗?为什么?


💡 核心记忆:SSRF 的本质不是“让服务器访问一个链接”,而是“借服务器的网络位置和身份去碰你碰不到的东西”。
#Security