<!-- title: ssrf -->
SSRF 服务端请求伪造详解:原理、利用与防御
一、漏洞原理
SSRF(Server-Side Request Forgery,服务端请求伪造)是指攻击者诱使服务器代替自己去发起网络请求,从而访问到攻击者从外部本无法触及的内部资源。前面几种漏洞的战场在浏览器和页面,SSRF 的战场则转到了服务器侧的网络位置——这使它成为内网渗透的第一块跳板。
漏洞根源依旧是那条熟悉的铁律:用户输入被当成了请求目标,而不是被当作数据处理。许多业务功能天然需要服务器向外发请求:网页预览/在线翻译(抓取 URL 生成快照)、导入远程头像、Webhook 回调、文档转码、支付回调验签等。如果"请求哪个地址"完全由用户参数决定且不加过滤,攻击者就可以把请求目标从公网改写成内网。
为什么这很危险?因为在云环境和数据中心里,服务器内网是一整片"信任区":内部管理后台往往不做鉴权(反正外网访问不到)、数据库/缓存/消息队列监听内网端口、云平台元数据服务(如 169.254.169.254)保存着实例凭证。SSRF 意味着攻击者"人在外网、手伸进了内网",因此它常年位居企业实战攻防中"打点→入内网"路线的首选起手式。 <!-- allow -->
二、示例代码
以下是一个典型的存在 SSRF 的"网页预览"功能(虚构站点 example.com):
<?php
// preview.php —— 用户提交 URL,服务器抓取内容生成预览
$url = $_GET['url'];
echo file_get_contents($url); // 致命点:目标地址完全由用户控制
?>攻击者把 url 参数从 https://example.com/article/1 改成内网地址,服务器就会去请求内网。修复后的安全写法采用"白名单 + 内网地址黑名单"双重校验:
<?php
// 安全版预览
$url = $_GET['url'] ?? '';
$host = parse_url($url, PHP_URL_HOST);
// 1. 协议白名单 + 域名白名单(业务上只允许抓取合作站点)
if (!preg_match('#^https://#', $url) || !in_array($host, $ALLOWED_HOSTS, true)) {
exit('目标不在允许范围内');
}
// 2. 解析出的 IP 不得落在内网/保留网段(防止用DNS重绑定绕过域名判断)
$ip = gethostbyname($host);
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
exit('非法目标');
}
echo file_get_contents($url, false, stream_context_create(['http' => ['follow_location' => 0]])); // 3. 禁止跟随重定向
?>三、三种典型 Payload(教学演示)
1. 内网端口探测
让服务器去请求内网的常见管理端口,根据响应差异判断存活:
?url=http://192.168.1.10:8080/ <!-- allow -->
?url=http://10.0.0.5:6379/ <!-- allow -->返回内容或耗时不同,即可绘制出一张内网地图。这是 SSRF 最基础的用法,也是内网横向的侦察阶段。
2. file 协议读取本地文件
不少底层函数支持非 HTTP 协议,若不过滤协议,可直接读取服务器文件:
?url=file:///etc/passwd
?url=file:///C:/Windows/win.ini一行参数就能把服务器系统文件读回来,说明协议白名单是 SSRF 防御的第一道闸。
3. 云元数据服务获取实例凭证
在云主机上,链路本地地址 169.254.169.254 是云平台的元数据服务,教材级的示意如下: <!-- allow -->
?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ <!-- allow -->历史上多起重大云安全事件正是通过 SSRF 触达元数据服务、进而窃取临时凭证导致的。正因如此,各大云厂商推出了"元数据服务加固版"(要求带 token 的请求),企业也应将其纳入 SSRF 防护的重点目标。
四、防御建议
- 协议白名单:只允许
http/https,禁用file、gopher、ftp、dict等一切非必要协议——gopher 协议甚至可以构造内网数据库报文,必须封死 - 目标白名单优先:业务上"需要请求谁"通常是确定的(固定 API、合作域名),能白名单就不要开放任意 URL
- 内网地址黑名单 + DNS 解析后校验:校验"解析出来的最终 IP"不在私网段(10/8、172.16/12、192.168/16、169.254/16、127/8 等),防止攻击者用"域名指向内网 IP"或 DNS 重绑定绕过表面的域名判断
- 禁止跟随重定向:攻击者常用"公网 302 跳转到内网"绕过首次校验,HTTP 客户端应关闭自动重定向或对每一跳重新校验
- 独立出口与最小权限:需要外呼功能的服务放入独立网段、通过统一代理出网,该代理收紧可达范围;实例角色/凭证按最小权限分配,即使 SSRF 成立也拿不到高价值凭证
- 元数据服务加固:云环境启用要求 token 的元数据访问模式,并在实例侧限制对 169.254.169.254 的访问 <!-- allow -->
五、总结
SSRF 把"不信任用户输入"这条军规从网页层延伸到了网络层:你的服务器会替攻击者的眼睛看内网。它的防御组合拳可以记成一句话——"协议锁死、目标白名单、解析后校验 IP、重定向重审、凭证最小化"。对安全学习者而言,SSRF 是理解"边界即信任"的最佳案例:外网与内网之间的每一道边界,都必须假设有人正从外面敲门。