PHP安全根
我的朋友在我的脚本中发现了一个问题,它允许访问根文件 此url提供passwd文件: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,从数据库中取出文件名和路径,然后下载。我想你有一个存储
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']))