PHP安全根

PHP安全根,php,security,root,Php,Security,Root,我的朋友在我的脚本中发现了一个问题,它允许访问根文件 此url提供passwd文件: http://site.com/attachment.php?file=../../../../../../etc/passwd 如何逃离这个安全漏洞?不要使用URL字符串下载文件。。。。定义唯一ID以表示文件,而不是路径 您可能看到过这样的下载http://www.mysite.com/download.php?id=23423他们做什么,使用这个id,从数据库中取出文件名和路径,然后下载。我想你有一个存储

我的朋友在我的脚本中发现了一个问题,它允许访问根文件

此url提供passwd文件:

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

如何逃离这个安全漏洞?

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


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

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

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

 // 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
并使用脚本。

您可以使用和检查URL(或任何“安全”下载的目录)

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


还有安全指令(以及从5.3开始的运行时选项)。

有几种不同的解决方案。 如果只有一个文件名,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配置选项<;code>open\u basedir

(参考)。正如@Starx所指出的,尽量避免使用文件路径作为文档的标识符(除了目录遍历之外,还有其他问题)。(@MartIX关于(md5)散列的想法可能有助于精益实现)。此外,最好不要以root用户身份运行服务器。请使用一个单独的用户,该用户在系统上只有完成其任务所必需的权限(也就是说,如果您的意思是只能访问根用户可读的文件,例如
/etc/shadow
/etc/passwd
当然是现代Unix中任何用户都可以读取的),那么如果有一个名为“passwd”的文件在附件目录中,代码也允许下载/etc/passwd?我不是PHP程序员,但我认为您应该更明确地说,要访问的文件应该以相同的方式形成:$filename=$attachments\u path。"/" . basename($\u GET['file']))