PHP 安全科普 · 防御向
PHP 中的 SSRF:是什么,怎么修
链接预览、Webhook、图片抓取、PDF 生成等功能都会让服务器去请求一个 URL。如果这个 URL 由访客控制,他们就能让你的服务器去访问他们自己够不着的地方。
最近更新
这是什么
服务器通常位于受信任的网络内部。它发出的请求能访问数据库、管理后台、其他微服务,以及会发放凭证的云实例元数据服务。SSRF 把任何“抓取 URL”功能都变成通往内网的代理。MITRE 把它归为 CWE-918,OWASP 有专门的防范速查表。
怎么发现
- 搜索从输入获取 URL 的
curl_setopt(... CURLOPT_URL ...)、file_get_contents($var)、fopen($var)、get_headers()以及 Guzzle 等 HTTP 客户端调用。 - 列出所有抓取远程内容的功能:Webhook、头像或图片导入、链接预览、订阅阅读器、PDF 或截图渲染、带外部实体的 XML 解析。
- 检查 Web 服务器的出站流量;访问
169.254.169.254、localhost或私有网段的意外请求是危险信号。
怎么修
- 只允许功能真正需要的主机和协议(通常只有
https),其余一律拒绝。 - 自己解析主机名,拒绝私有、回环和链路本地地址,然后直接连接解析出的 IP,避免检查和使用之间 DNS 被改。
- 关闭重定向跟随(
CURLOPT_FOLLOWLOCATION设为 false),并用CURLOPT_PROTOCOLS限制协议。 - 在云主机上要求实例元数据使用会话令牌(例如 AWS IMDSv2),并用防火墙限制出站。
只读检查与安全写法
# Find server-side fetches that may take a user-supplied URL (read-only)
grep -rnE "(curl_setopt.*CURLOPT_URL|file_get_contents\s*\(\s*\$|fopen\s*\(\s*\$)" --include=*.php . | grep -v /vendor/
// Allowlist hosts and schemes before fetching
$u = parse_url($url);
$allowed = ['api.example.com'];
if (($u['scheme'] ?? '') !== 'https' || !in_array($u['host'] ?? '', $allowed, true)) {
throw new RuntimeException('URL not allowed');
}
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);屏蔽 127.0.0.1 就够了吗?
不够。其他 IP 写法、IPv6、解析到私有地址的域名和重定向都能绕过简单黑名单,OWASP 建议用白名单。
WAF 能挡住 SSRF 吗?
能拦一部分模式,但它不知道哪些内网主机对你重要,还是要在代码里修。
其他常见 PHP 漏洞类型
- PHP 对象注入:是什么,怎么修当用户可控的输入进入 unserialize() 时就会发生 PHP 对象注入,它可以实例化对象,并通过魔术方法执行攻击者选定的逻辑。
- PHP 文件包含(LFI/RFI):是什么,怎么修当用户输入控制了 include 或 require 的路径时就会发生文件包含,攻击者可以读取本地文件(LFI),在开启 allow_url_include 时还能运行远程代码(RFI)。
- PHP 中的 XSS:是什么,怎么防当 PHP 页面把用户可控的数据不经转义输出到 HTML 时就会发生跨站脚本(XSS),攻击者的脚本会在其他访客的浏览器里运行。
- phpinfo() 暴露:为什么重要,怎么修公开的 phpinfo() 页面会泄露精确的 PHP 版本、已加载模块、文件路径,常常还有环境变量或密钥,帮攻击者瞄准 PHP2Shell 这类漏洞。
来源
出站链接将离开本站。本站不托管利用代码。
- CWE-918: Server-Side Request Forgery (SSRF) — MITRE CWE
- Server-Side Request Forgery Prevention Cheat Sheet — OWASP Cheat Sheet Series