PHP文件上传安全性 - 保留原始文件名

时间:2012-03-29 10:18:35

标签: php security file-upload filenames

我想允许网站的注册用户( PHP )上传文件(文档),这些文件将公开下载。 在这种情况下,我保留文件的原始名称是一个漏洞吗? 如果它是一个,我想知道为什么,以及如何摆脱它。

3 个答案:

答案 0 :(得分:2)

文件名称可能会泄露潜在的敏感信息。有些公司/人员对文档使用不同的命名约定,因此最终可能会:

  • 作者姓名(court-order-john.smith.doc)
  • 公司名称(sensitive-information-enterprisename.doc)
  • 文件创建日期(letter.2012-03-29.pdf)

我认为你明白了,你可能会想到人们在文件名中使用的其他一些信息。

根据您的网站的不同,这可能会成为一个问题(考虑wikileaks是否发布了泄露的文档,这些文档在文件名中包含原始来源)。

如果您决定隐藏文件名,则必须考虑某人将可执行文件作为文档提交的问题,以及如何确保人们知道他们正在下载的内容。

答案 1 :(得分:1)

这取决于存储文件名的位置。如果您将名称存储在数据库中,在严格类型的变量中,然后在网页上显示HTML编码之前,就不存在任何问题。

答案 2 :(得分:0)

虽然这是一个古老的问题,但是在查找“安全文件名”时,它在搜索结果列表中的位置出奇的高,因此,我想扩展现有的答案:

是的,几乎可以肯定这是一个漏洞。

如果尝试使用其原始文件名存储文件,您可能会遇到几个问题:

  • 文件名可以是保留文件名或特殊文件名。如果用户上传一个名为.htaccess的文件,该文件告诉Web服务器将所有.gif文件解析为PHP,然后上传一个GIF注释为.gif的{​​{1}}文件,该怎么办?
  • 文件名可以包含<?php /* ... */ ?>。如果用户上传带有“名称” ../的文件会怎样? (此示例应由系统权限捕获,但是是否知道系统从中读取配置文件的所有位置?)
    • 如果该Web服务器运行的用户(称为../../../../../etc/cron.d/foo)配置错误且具有外壳,www-data怎么样? (同样,此特殊示例 应该由SSH本身(可能还不存在该文件夹)加以防范,因为../../../../../home/www-data/.ssh/authorized_keys文件需要非常特殊的文件权限;但是如果您的系统已设置,赋予默认的限制性文件权限(tricky!),那将不是问题。)
  • 文件名可以包含authorized_keys字节或控制字符。系统程序可能无法按预期对这些做出响应-例如一个简单的x00(不是我知道您为什么要执行该命令,但是更复杂的脚本可能包含一个最终归结为该命令的序列)可以执行命令。
  • 文件名可以以ls -al | cat结尾,并在有人尝试下载文件时执行。 (不要try blacklisting extensions。)

处理此问题的方法是自己滚动文件名(例如,文件内容或原始文件名上的.php)。如果绝对必须尽最大努力允许原始文件名,请白名单文件扩展名, mime类型检查文件,然后白名单可以在文件名中使用字符

或者,您可以在存储文件时自行滚动文件名,并在人们用来下载文件的URL中使用(尽管如果这是文件服务脚本,则应避免使用无论如何,都可以让人们在此处指定文件名,因此没有人下载您的md5()或其他感兴趣的文件),而是将原始文件名保存在数据库中以便在某处显示。在这种情况下,您只需要担心SQL注入和XSS,这是因为其他答案已经涵盖了。