PHP防范SSRF核心是主动校验URL协议与目标地址:仅允http/https,禁用file://等高危协议;须parse_url()提取scheme、DNS解析host并校验IP是否属私有网段;禁用cURL重定向、关闭allow_url_fopen,并通过架构解耦与日志审计纵深防御。

PHP中防范SSRF漏洞,核心是切断“用户输入→服务端发起请求”这条未经约束的通路。不是靠某个函数开关或版本升级自动解决,而是必须在业务逻辑层主动校验、限制和隔离。
严格校验URL协议与目标地址
所有外部请求入口必须强制白名单协议,仅允许 http 和 https;彻底禁用 file://、gopher://、dict://、ftp://、ldap:// 等高危协议。不能只靠 filter_var($url, FILTER_VALIDATE_URL) 做格式判断——它不检查协议安全性,也不识别内网地址。
- 用
parse_url()提取 scheme 和 host - 检查
scheme是否在允许列表中 - 对
host做真实 DNS 解析(如gethostbyname()或dns_get_record()),再判断解析出的 IP 是否属于私有地址段(127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、100.64.0.0/10、::1、fe80::/10 等) - 拒绝
localhost、local、host.docker.internal等易被解析为内网的别名
限制cURL和file_get_contents行为
即使URL通过了初步校验,也要防止运行时绕过。cURL 默认支持重定向和多种协议,file_get_contents 默认启用所有流包装器,必须显式收紧。
- 设置
CURLOPT_FOLLOWLOCATION = false,禁用 30x 自动跳转(防 DNS Rebinding 和跳转绕过) - 设置
CURLOPT_MAXREDIRS = 0 - 设置
CURLOPT_TIMEOUT和CURLOPT_CONNECTTIMEOUT防止耗时探测 - 调用
file_get_contents前,确保allow_url_fopen = Off(php.ini 级别关闭) - 禁用危险流包装器:
stream_wrapper_unregister('file')(慎用,需确认不影响正常功能)
从架构层面降低风险
单靠代码校验容易遗漏边界情况,应结合部署与设计做纵深防御。
- 将发起外网请求的功能剥离到独立服务(如专用代理服务),主应用不直接联网
- 该代理服务部署在受限网络环境中,仅允许访问明确授权的域名/IP,配合防火墙策略
- 容器化部署时,禁用默认网桥,使用 host 网络或自定义网络并限制 outbound 流量
- 关键请求添加签名或 Token 验证,确保 URL 是由可信模块生成,而非用户任意构造
- 记录所有外发请求的目标、响应状态和耗时,异常行为(如高频内网IP尝试)触发告警
ThinkPHP等框架场景特别注意
ThinkPHP 没有内置 SSRF 防护中间件,middleware.csrf 对 SSRF 完全无效。常见风险点包括远程图片加载、Webhook 回调、文档预览、OSS 回源地址拼接等。
- 不要写
$url = input('url'); file_get_contents($url); - 所有涉及
input()获取 URL 的地方,必须封装校验函数,且校验逻辑要包含 DNS 解析+IP 段判断 - 避免使用
curl_init($_GET['url'])这类直传方式,统一走安全封装后的请求方法 - 正则过滤域名时,拒绝含
@、//、\、%00等畸形字符的输入
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











