我有一个关于这是多么安全的问题。我已经编写了一个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而不是原始扩展名,当用户下载文件时可能会替换原始扩展名(可能有点超过顶部)。
答案 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,并且所有
当用户想要获取文件时,脚本访问数据库并获取真实文件名,旧文件名和扩展名,它告诉用户浏览器文件的名称是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>