这样安全吗? (PHP下载脚本)

时间:2011-02-09 17:31:38

标签: php security download

我有一个关于这是多么安全的问题。我已经编写了一个php强制下载脚本,实际为该文件提供服务的部分看起来应该很熟悉:

header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Length: ' . filesize("user_files/".$temp_actual));
header('Content-Disposition: attachment; filename="'.$filename."\"");
readfile("user_files/".$temp_actual);

$filename是他们看到的文件名,$temp_actual是我服务器上的REAL文件名。显然,在此之上有一大堆代码可以防止发生不良事件,但基本上,用户应该能够下载他们上传的任何内容。如果他们上传.php文件,我真的不希望它在服务器上运行,我希望它通过force downoad传递给他们(他们需要能够上传任何文件类型)

它按预期工作,所有文件扩展名都被强制下载,但我只是想确保他们无法在我的服务器上运行任何php或html文件。

其他信息

user_files在网站root中但是.htaccess“拒绝所有人” user_files目录中的每个文件都附加.file而不是原始扩展名,当用户下载文件时可能会替换原始扩展名(可能有点超过顶部)。

4 个答案:

答案 0 :(得分:3)

您网站中的user_files文件夹是否为root?如果是这样,他们可以上传一个php文件并导航到http://mysite.com/user_files/somefile.php并运行代码。当然,他们需要知道文件的临时名称,但如果您还没有,则应确保您的Web服务器设置为不允许从该文件夹提供页面(或将其移出文档外部)根)。

答案 1 :(得分:2)

清理文件名。有人会尝试上传.htaccess来替换您的。{/ p>

即使您使用.file替换了扩展程序,也有人会尝试上传.htaccess\0.txt,这会因a bug而生效。

有人会尝试.\301\250taccess(无效的UTF-8序列可能会解码为h)。

此外,有人会尝试下载../../../../../etc/shadow

如果您使用的是Windows,则有人会尝试.HTACCESS..\..\..\..\..\windows\system32\conf\sam

此处"user_file/".$temp_actual部分很重要:它可以阻止触发URL-like filenames。也许对这个效果发表评论所以它不会被重构。

要完全确定,如果方便,请将文件名编码为安全字符。例如。 strtr(base64_encode($filename), '/', '_')

答案 2 :(得分:1)

好的答案是:

这样做似乎很安全。对于你们所有人都在谈论输入过滤等问题。让我给你一个快速的低点:

听听大家,显然有更多的检查涉及所以请不要回复用户可以上传xx.xx并覆盖你的xx或从/../../../../下载xx虽然我很感激你帮助我应该重新解决一下这个问题。假设上传和下载是气密的。

示例filename evil.php

  • 上传脚本获取用户文件 除去任何不是: A-ZA-Z0-9,!-_

  • 然后删除扩展名,将其和真实姓名存储在数据库中#(和新文件名)

  • 重命名文件让我们说12345.file并存储在user_files

  • user_files的CHMOD为700,并且所有

  • 的.htaccess读数被拒绝
  • 当用户想要获取文件时,脚本访问数据库并获取真实文件名,旧文件名和扩展名,它告诉用户浏览器文件的名称是oldfilename.extension(evil。但是它仍然在文件系统上作为12345.file。然后它为下载设置标题,并使用readfile()将内容读取到浏览器。

要检查用户无法将我的服务器转到PARSE php,我注释掉了打开保存文件下载框的标题,并且只使用了readfile()。结果是php被转储到页面,但 NOT PARSED 。使用eval()进一步测试表明它也没有被解析。哪个是最有帮助的。 =)

(在阅读之后,上面的标题应该从 application / force-download 更改为 application / octet-stream (正确的mime类型)。< / p>

感谢所有回复你所有帮助的人 - 我希望这可以为将来偶然发现这个问题的人清除一些内容!

和平!

答案 3 :(得分:0)

您是否考虑过在上传时更改(附加)文件扩展名? 说myFile.php变为myFile.php.txt

你仍然可以通过使用像substr()这样的东西来显示文件(用于下载目的)。但是扩展名为.txt会使它们无法在服务器上实际运行 - 无论目录层次结构/位置如何。< / p>