共计 1506 个字符,预计需要花费 4 分钟才能阅读完成。
背景与漏洞描述
SSRF(Server-Side Request Forgery)服务端请求伪造漏洞,是指攻击者构造恶意请求,诱使服务器向内部或第三方系统发起非预期请求。在 ChatGPT 的 pictureproxy.php 组件中,由于未对用户提供的 URL 参数进行严格校验,导致攻击者可利用该接口访问任意内网服务(如数据库管理界面、Redis 等),甚至通过协议转换(如 file:///、gopher://)读取服务器本地文件。

典型攻击场景:
- 攻击者提交包含内网 IP 的 URL 参数(如
http://192.168.1.1/admin) - 服务器代理请求该地址并返回响应内容
- 通过响应差异判断内网服务存活状态
漏洞复现
使用 curl 模拟攻击请求(需替换实际域名):
curl -v 'https://chat.example.com/pictureproxy.php?url=http://169.254.169.254/latest/meta-data/'
关键特征:
– 返回 AWS 元数据服务内容(证明存在 SSRF)
– 响应头包含X-Proxy-Origin: pictureproxy.php
修复方案
输入验证实现
修复前存在问题的代码片段:
$targetUrl = $_GET['url']; // 直接使用未过滤的用户输入
$image = file_get_contents($targetUrl);
修复后代码应包含以下验证:
- 检查 URL 协议(仅允许 http/https)
- 解析域名并验证是否为允许的外部域名
- 禁用 IP 地址直接访问
URL 白名单机制
$allowedDomains = [
'cdn.openai.com',
'example-cdn.com'
];
function isAllowedUrl($url) {
global $allowedDomains;
// 协议检查
if (!preg_match('/^https?:\/\//i', $url)) {return false;}
// 提取主机名
$host = parse_url($url, PHP_URL_HOST);
// 禁止 IP 地址
if (filter_var($host, FILTER_VALIDATE_IP)) {return false;}
// 白名单校验
return in_array($host, $allowedDomains);
}
权限控制实践
- 在 php.ini 中禁用危险协议:
allow_url_fopen = Off allow_url_include = Off - 使用专用网络隔离代理服务器
- 为 pictureproxy.php 配置独立的低权限系统账户
防御措施
网络层防护
- 配置防火墙规则限制出站流量
- 禁用服务器到 metadata 服务的访问(AWS/IaaS 环境)
- 使用 VPC 端点限制内网服务暴露
应用层防护
- 实现请求签名机制(如 HMAC)
- 设置 User-Agent 黑名单(阻断常见扫描工具)
- 添加速率限制(如每分钟 10 次请求)
监控策略
- 日志记录所有代理请求,包括:
- 原始客户端 IP
- 请求时间
- 目标 URL
- 响应状态码
- 设置告警规则检测异常模式:
- 短时间内大量 404 响应
- 对内部域名的请求
避坑指南
常见错误及解决方案:
- 错误:仅校验域名前缀
- 问题:
evil.com.openai.com可通过检查 -
修复:严格匹配完整域名
-
错误:依赖客户端重定向
- 问题:攻击者可构造 30x 跳转绕过检查
-
修复:服务端跟踪重定向链并逐级验证
-
错误:白名单维护困难
- 方案:采用动态配置系统(如 Consul)管理白名单
总结与延伸
建议在代码审查阶段重点关注:
- 所有接受 URL 输入的场景
- 文件操作相关函数的使用
- 反序列化操作的处理
扩展防护思路:
– 部署 WAF 规则拦截 SSRF 特征请求
– 定期进行黑盒渗透测试
– 建立漏洞奖励计划收集外部报告
正文完
发表至: 未分类
近一天内
