PHP安全根

时间:2010-08-22 07:48:06

标签: php security root

我的朋友在我的脚本中发现了一个问题,它可以访问根文件。这个网址提供了passwd文件:

http://site.com/attachment.php?file=../../../../../../etc/passwd

如何逃避此安全漏洞?

4 个答案:

答案 0 :(得分:14)

请勿使用URL字符串下载文件....定义唯一ID以表示文件,而不是路径。

你可能已经看过这样的下载http://www.mysite.com/download.php?id=23423他们做了什么,使用这个id,从数据库中取出文件名和路径,然后下载它。

答案 1 :(得分:4)

有几种不同的解决方案。 如果只能有文件名,则basename()解决方案可以正常工作。

但是,如果它可以是路径,则需要更复杂的解决方案

//assume current directory, but can be set anything. Absolute path of course
$basedir   = dirname(__FILE__);
//assume our files are below document root. 
//Otherwise use it's root dir instead of DOCUMENT_ROOT
$filename  = realpath($_SERVER['DOCUMENT_ROOT'].$_GET['file']);
if (substr($filename,0,strlen($basedir)) !== $basedir) {
  header ("HTTP/1.0 403 Forbidden"); 
  exit; 
}

还有一个有用的PHP配置选项open_basedir

答案 2 :(得分:3)

您可以使用realpath()dirname()来检查针对$_SERVER['DOCUMENT_ROOT']的网址(或任何目录下载的“安全”)。

如果realpath()的结果指向安全目录之外,则可以拒绝下载请求。

还有open_basedir安全指令(和5.3之后的运行时选项)。

答案 3 :(得分:1)

我想你有一个存储所有附件的目录。

只测试文件是否位于您的目录中。

 // http://www.php.net/manual/en/function.basename.php
 // http://cz.php.net/manual/en/function.file-exists.php 
 if (file_exists($attachments_path . "/" . basename($_GET['file'])) {
  // do work
 }

Starx发布了一个似乎很好的解决方案。但是,它可以在没有数据库的情况下完成。如果有人上传文件,您可以将文件存储为md5($filename).$extension并使用您的脚本。