阻止人们通过表单上传恶意PHP文件

Ben*_*Rae 29 php security upload zip

我有一个在我的网站上用PHP创建的上传表单,人们可以上传一个zip文件.然后提取zip文件,并将所有文件位置添加到数据库中.上传表单仅供人们上传图片,显然,文件在zip文件夹中我无法检查文件被提取之前要上传的文件.我需要一段代码来删除所有非图像格式的文件(.png,.jpeg等).我真的很担心人们能够上传恶意的php文件,存在很大的安全风险!我还需要注意人们改变php文件的扩展,试图绕过这个安全功能.

这是我使用的原始脚本http://net.tutsplus.com/videos/screencasts/how-to-open-zip-files-with-php/

这是实际提取.zip文件的代码:

function openZip($file_to_open) {
    global $target;

    $zip = new ZipArchive();
    $x = $zip->open($file_to_open);
    if($x === true) {
        $zip->extractTo($target);
        $zip->close();

        unlink($file_to_open);
    } else {
        die("There was a problem. Please try again!");
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢,本.

bob*_*nce 65

我真的很担心人们能够上传恶意的php文件,安全隐患很大!

冰山一角!

我还需要注意人们改变php文件的扩展,试图绕过这个安全功能.

通常,更改扩展名将阻止PHP将这些文件解释为脚本.但这不是唯一的问题.除了'...... php'之外还有更多可能会损害服务器端的东西; '.htaccess'和设置了X位的文件是显而易见的,但绝不是你要担心的.即使忽略服务器端的东西,也存在巨大的客户端问题.

例如,如果某人可以上传".html"文件,他们可以在其中包含一个<script>标记,用于劫持第三方用户的会话,并删除所有上传的文件或更改其密码等.这是一种典型的跨站点脚本(XSS)攻击.

此外,由于某些浏览器(主要是IE)的"内容嗅探"行为,上传为".gif"的文件实际上可能包含恶意HTML等.如果IE在文件开头附近看到(但不限于)'<html>'的告密者,它可以忽略所提供的'Content-Type'并显示为HTML,从而产生XSS.

此外,还可以制作一个文件可以是您的图像解析器可以接受的有效图像,也可以包含嵌入式HTML.根据用户浏览器的确切版本和图像文件的确切格式,有各种可能的结果(特别是JPEG具有非常可变的一组可能的标题格式).IE8中有缓解措施,但现在没有用,你不得不想知道为什么他们不能简单地停止进行内容嗅探,你痴迷于MS,而不是让我们对HTTP标头的非标准扩展负担.刚刚开始工作.

我又陷入了咆哮.我会停下来 安全地提供用户提供的图像的策略:

1:切勿使用从用户输入获取的文件名将文件存储在服务器的文件系统中.这可以防止错误和攻击:不同的文件系统对文件名中允许的字符有不同的规则,并且比你想象的"清理"文件名要困难得多.

即使您采取了非常严格的限制,例如"只有ASCII字母",您仍然需要担心太长,太短和保留的名称:尝试保存一个名称与"com.txt"无关的文件Windows服务器并观看您的应用程序.您是否知道应用程序可能运行的每个文件系统的路径名称的所有奇怪缺陷?信心?

而是在数据库中存储文件详细信息(例如名称和媒体类型),并在文件存储中使用主键作为名称(例如"74293.dat").然后,您需要一种方法来为它们提供不同的明显文件名,例如下载文件的下载程序脚本,执行Web服务器内部重定向的下载程序脚本或URL重写.

2:使用ZipArchive非常非常小心.在相同类型的extractTo中存在遍历漏洞,这些漏洞影响了大多数天真的基于路径的ZIP提取器.此外,你可以接受ZIP炸弹的攻击.最好避免文件名错误的危险,通过逐步浏览存档中的每个文件条目(例如使用zip_read/zip_entry_*)并在手动将其流解压缩到具有已知良好名称和模式标志的文件之前检查其详细信息,在没有档案帮助的情况下生成.忽略ZIP中的文件夹路径.

3:如果您可以加载图像文件并将其再次保存,特别是如果您以某种方式处理它(例如调整大小/缩略图或添加水印),您可以合理地确定结果将是清洁.从理论上讲,有可能制作一个针对特定图像压缩器的图像,这样当它被压缩时,结果看起来也像HTML,但这对我来说似乎是一次非常困难的攻击.

4:如果您可以将所有图像作为下载提供(即在下载程序脚本中使用"内容处理:附件"),那么您可能很安全.但这可能给用户带来太多不便.这可以与(3)协同工作,但是,在线提供较小的处理图像,并且仅提供原始的高质量图像作为下载.

5:如果您必须内联提供未经更改的图像,则可以通过从其他域提供服务来消除跨站点脚本风险.例如,对于不受信任的图像使用'images.example.com',对于包含所有逻辑的主站点使用'www.example.com'.确保cookie仅限于正确的虚拟主机,并且虚拟主机已设置为无法响应除其正确名称之外的任何内容(另请参阅:DNS重新绑定攻击).这是许多webmail服务的功能.

总之,用户提交的媒体内容是一个问题.

总结,AAAARRRRRRRGGGGHHH.

ETA评论:

在顶部你提到'有X位设置的文件',你是什么意思?

我不能说话,ZipArchive.extractTo()因为我没有测试它,但是当被要求从存档中转储文件时,许多提取器将重新创建与每个文件关联的[某些] Unix文件模式标志(如果存档是在一个Unix,所以实际上有模式标志).如果缺少所有者读取权限,这可能会导致权限问题.但如果您的服务器启用了CGI,它也可能是一个安全问题:X位可以允许将文件解释为脚本并传递给第一行hashbang中列出的任何脚本解释器.

我以为.htaccess必须在主目录中,是不是这样?

取决于Apache的设置方式,特别是AllowOverride指令.通用主机通常在任何目录上使用AllowOverride.

如果有人仍然上传像./var/www/wr_dir/evil.php这样的文件,会发生什么?

我希望领先的'..'将被丢弃,这就是遭受同样漏洞的其他工具所做的.

但我仍然不相信extractTo()反对恶意输入,有太多奇怪的小文件名/目录树的东西可能出错 - 特别是如果你期望永远在Windows服务器上运行.zip_read()使您能够更好地控制解密过程,因此攻击者更少.


Gum*_*mbo 15

首先,您应该禁止每个没有正确图像文件扩展名的文件.之后,您可以使用该getimagesize功能检查文件是否是常规图像文件.

但此外,您应该知道某些图像格式允许注释和其他元信息.这可以用于恶意代码,例如某些浏览器在某些情况下将执行的JavaScript(请参阅Internet Explorer中的Risky MIME嗅探).


Joh*_*ood 9

那你应该不仅仅依赖于文件扩展名.尝试通过图像库传递每个文件,以验证它真的是一个图像.