简体   繁体   English

在PHP的fopen()的文件名前加上“ http://”是否足够安全,可以防止读取本地文件?

[英]Is prepending “http://” to a filename for PHP's fopen() safe enough to prevent reading local files?

I have a PHP script that accepts a file URL by GET and opens it with fopen. 我有一个PHP脚本,该脚本通过GET接受文件URL,并使用fopen打开它。
Is this solution safe enough or is it a security breach? 此解决方案是否足够安全还是违反安全性?

$filename = $_GET['file'];
if( substr( $filename, 0, 7 ) !== 'http://' )
    $filename = 'http://'.$filename;

fopen( $filename, 'r' );
// etc...

This way you can't force a local path to the script to read from it. 这样,您就不能强制脚本的本地路径从中读取。

That should work, but here are two more things to think about: 应该起作用,但是这里还有两件事要考虑:

  • Giving access to other servers. 允许访问其他服务器。 If your server is behind a firewall, someone could use this to fetch data from another server behind your firewall (or hit a service, etc.) using HTTP, FTP, etc. 如果您的服务器位于防火墙后,则有人可以使用它通过HTTP,FTP等从防火墙后的另一台服务器中获取数据(或访问服务等)。

  • Recursive denial of service. 递归拒绝服务。 Make sure that there's not a way for someone to give you the URL of the script itself to fetch in a way that makes a recursion loop. 确保没有任何人可以给您提供脚本本身的URL的方式来进行递归循环。

Not exactly sure, but you might need to escape it also to be safe. 不确定,但是为了安全起见,可能还需要转义它。

$filename=escapeshellarg ( $filename );

See: http://php.net/manual/en/function.escapeshellarg.php 请参阅: http//php.net/manual/en/function.escapeshellarg.php

It's sort of fragile, as the security depends on the http handler being registered. 这有点脆弱,因为安全性取决于所注册的http处理程序。 What if in a future version of PHP it will be removed or optional? 如果在将来的PHP版本中将其删除或可选怎么办?

Here's the problem. 这是问题所在。 This actually works (after a warning): 这实际上有效(警告之后):

stream_wrapper_unregister('http');
file_get_contents('http://../../../../../etc/passwd');

另一个安全措施/选项是使用chroot() http://php.net/manual/en/function.chroot.php

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM