2019年,漏洞Capital One银行被一个前AWS员工用SSRF漏洞拖走了1亿多用户的漏洞信贷数据。她没黑进数据库,漏洞没破解密码,漏洞只是漏洞让银行的服务器替她发了一个请求。
这就是漏洞SSRF的核心:你让一台服务器去访问它本来不该访问的东西。服务器信任自己内部网络,漏洞防火墙也信任它。漏洞攻击者站在外面,漏洞借服务器的漏洞身份走进内网,像刷员工卡一样顺畅。漏洞
很多应用需要从URL抓取内容。比如你贴一个图片链接,漏洞后台帮你下载;你填一个webhook地址,漏洞系统帮你回调测试。漏洞这些功能如果没做校验,用户就能控制服务器发起请求的目标地址。
把 url= 后面那串换成 http://169.254.169.254/latest/meta-data/,在云服务器上就能读到实例的临时凭证。AWS、阿里云、腾讯云,元数据接口的地址几乎都是这个。拿到凭证等于拿到了这台机器在云上的身份,能调API、能读对象存储、能横向移动。
换成 http://127.0.0.1:6379/,如果内网跑着未授权的Redis,可以直接写crontab反弹shell。换成 http://10.0.0.5:8080/admin,内网管理后台没有任何认证,因为运维觉得“外网访问不到”。
我见过一个真实案例。某电商的退货系统有个功能:输入物流单号,后台去快递100查状态。参数是完整的URL。安全测试时改成内网地址,直接返回了内部GitLab的登录页。再配合gopher协议打Redis,从退货查询到服务器沦陷,整条链路不到二十分钟。
SQL注入要构造payload,XSS要绕过CSP,SSRF很多时候只需要改一个URL。利用门槛低到离谱。
更麻烦的是,它经常出现在“看起来没问题”的地方。PDF生成服务要加载外部图片、OA系统要预览在线文档、监控平台要探测URL可用性——这些功能天然需要发起网络请求,开发者往往只校验了协议头是不是http,没管目标IP是不是内网。
还有一层:SSRF能绕过基于IP的访问控制。内网服务看到请求来自10.0.1.50,以为是兄弟系统,直接放行。零信任架构喊了这么多年,很多内网服务之间的信任仍然是默认的。
云环境把这个问题放大了。以前内网渗透要先进边界,现在一个SSRF可能直接摸到元数据服务。K8s集群里,Pod的service account token挂在 /var/run/secrets/,如果SSRF能读文件(通过file协议或gopher打内网服务),集群权限就到手了。
很多人第一反应是禁用 127.0.0.1 和 169.254.169.254。绕过方式太多了:十进制IP、八进制、IPv6映射、DNS重绑定、302跳转。黑名单永远追不上绕过姿势。
靠谱的做法是白名单。只允许访问特定的域名或IP段,其他一律拒绝。如果业务场景确实需要用户自定义URL,那就把请求发到一个隔离的代理服务,代理层做DNS解析后的IP校验,并且禁止跳转。
云厂商也在做事。AWS的IMDSv2要求token才能访问元数据,一定程度上挡住了简单的SSRF。但很多老实例还在用v1,图省事。
我的判断是:只要应用还需要“从URL取内容”这个功能,SSRF就不会消失。它不像SQL注入那样有成熟的ORM框架帮你兜底,每个URL参数都得开发者自己盯着。漏一个,可能就是一整片内网。
Capital One那件事之后,美国监管罚了银行8千万美元。一个SSRF,代价是8千万加1亿用户数据。这笔账,怎么算都不划算。