使用第三方外部URL作为参数时,PHP的fread()、file()与file_get_contents()函数是否对服务器安全?
关于PHP中file_get_contents()等函数处理外部URL的安全性疑问解答
一、函数本身是否存在已知漏洞?
首先可以明确:file_get_contents()、file()、fread()这些函数本身处理外部URL时,没有已知的能直接导致服务器被入侵的漏洞——只要你不把返回的内容用eval()、include()这类危险函数执行(你已经明确不会这么做),单纯读取外部URL内容的行为,函数自身是安全的。
这些函数处理外部URL时,本质是PHP调用内置的HTTP/HTTPS协议客户端发起网络请求,获取远程内容后返回字符串。风险并不来自函数本身,而是来自对请求目标的控制不当,也就是下面要讲的SSRF风险。
二、你提供的代码存在哪些安全问题?
你的代码虽然做了简单的URL校验,但仍然有不少风险:
- SSRF(服务器端请求伪造)风险:
你的preg_match('/^https?://.+$/'规则非常容易绕过。比如攻击者可以输入http://127.0.0.1:3306(访问本地MySQL服务)、http://169.254.169.254/latest/meta-data/(云服务器的元数据服务,可能获取密钥),或者http://example.com@evil-domain.com(看起来是example.com,实际请求evil-domain.com),这些都会让你的服务器向攻击者指定的目标发起请求,可能泄露内网信息、触发内网服务的敏感操作,甚至导致服务器被控制。 - DoS(拒绝服务)风险:
攻击者可以输入一个返回超大内容的URL,或者响应极慢的URL,file_get_contents()会一直等待响应并读取内容,消耗服务器的内存和带宽,甚至拖垮整个应用。 - URL校验不严谨:
你提到已经知道这个正则太简化,补充一下:除了长度限制,还需要验证URL的域名合法性(比如禁止私有IP、内网地址),使用parse_url()来解析URL而非单纯依赖正则,避免各种绕过手段。
三、请求会携带客户端的Cookie或数据吗?
可以100%确认:默认情况下,这些函数发起的请求不会携带任何用户浏览器发送给你的应用的HTTP数据——包括Cookie、POST参数、请求头等等。
PHP发起的这个请求是一个全新的、独立的服务器端请求,和用户的客户端请求完全隔离。只有当你通过stream_context_create()手动创建上下文,明确添加Cookie、请求头或者其他参数时,才会把这些信息发送给第三方网站。
举个例子,只有像下面这样写,才会携带自定义的Cookie:
$context = stream_context_create([ 'http' => [ 'header' => "Cookie: foo=bar\r\n" ] ]); file_get_contents($user_url, false, $context);
四、内部文件 vs 外部URL的处理差异
你感觉两者机制不同是对的:
- 当传入内部文件路径(比如
includes/my-file.php)时,这些函数直接和服务器的文件系统交互,打开并读取本地文件,风险点主要是路径遍历攻击(比如通过../../etc/passwd读取敏感系统文件)。 - 当传入外部URL(比如
https://example.com)时,PHP会调用对应的协议处理模块(比如HTTP模块),发起一个网络请求,获取远程服务器返回的内容,风险点主要是SSRF、DoS这类网络层面的攻击。
内容的提问来源于stack exchange,提问作者covaleski
相关产品推荐
相关产品推荐

