首先,要意识到上传文件意味着用户以各种格式提供 a lot 数据,并且用户可以完全控制该数据 . 那个's even a concern for a normal form text field, file uploads are the same and a lot more. The first rule is: Don't信任任何一个 .
您通过文件上传从用户获得的内容:
文件数据
文件名
一个MIME类型
这些是文件上载的三个主要组件,并且没有一个是可信任的 .
不信任 $_FILES['file']['type'] 中的MIME类型 . 这是一个完全随意的用户提供的 Value .
Don 't use the file name for anything important. It'是一个完全随意的用户提供的值 . 您不能信任文件扩展名或一般名称 . 不要使用 'dir/' . $_FILES['file']['name'] 之类的文件将文件保存到服务器的硬盘上 . 如果名称是 '../../../passwd' ,则表示您正在覆盖其他目录中的文件 . 始终自己生成随机名称以将文件另存为 . 如果需要,可以将原始文件名作为元数据存储在数据库中 .
4 回答
这里是其中的一些:
当文件上传到服务器时,PHP会将变量$ _FILES ['uploadedfile'] ['type']设置为客户端使用的Web浏览器提供的mime类型 . 但是,文件上载表单验证不能仅依赖于此值 . 恶意用户可以使用脚本或其他允许发送HTTP POST请求的自动应用程序轻松上传文件,这允许他发送假的mime类型 .
编译包含攻击者可以使用的所有可能扩展名的列表几乎是不可能的 . 例如 . 如果代码在托管环境中运行,通常这样的环境允许大量脚本语言,例如Perl,Python,Ruby等,并且列表可以是无穷无尽的 .
有一些通用规则可以避免文件上传的一般问题:
在您的网站根文件夹下存储上传的文件 not - 因此用户将无法重写您的应用程序文件并直接访问上传的文件(例如,当您的应用程序位于 /var/www 时,在 /var/uploads 中) .
在数据库和物理文件中存储已清理的文件名称会给出文件哈希值的名称(这也解决了存储文件重复的问题 - 它们将具有相等的哈希值) .
为避免文件系统出现问题,以防/ var / uploads文件夹中的文件太多,请考虑将文件存储在文件夹树中,如下所示:
file hash = 234wffqwdedqwdcs
- >将其存储在/var/uploads/23/234wffqwdedqwdcs
中common rule:
/var/uploads/<first 2 hash letters>/<hash>
首先,要意识到上传文件意味着用户以各种格式提供 a lot 数据,并且用户可以完全控制该数据 . 那个's even a concern for a normal form text field, file uploads are the same and a lot more. The first rule is: Don't信任任何一个 .
您通过文件上传从用户获得的内容:
文件数据
文件名
一个MIME类型
这些是文件上载的三个主要组件,并且没有一个是可信任的 .
不信任
$_FILES['file']['type']
中的MIME类型 . 这是一个完全随意的用户提供的 Value .Don 't use the file name for anything important. It'是一个完全随意的用户提供的值 . 您不能信任文件扩展名或一般名称 . 不要使用
'dir/' . $_FILES['file']['name']
之类的文件将文件保存到服务器的硬盘上 . 如果名称是'../../../passwd'
,则表示您正在覆盖其他目录中的文件 . 始终自己生成随机名称以将文件另存为 . 如果需要,可以将原始文件名作为元数据存储在数据库中 .永远不要让任何人或任何人随意访问该文件 . 例如,如果攻击者将
malicious.php
文件上传到您的服务器并将其存储在您站点的webroot目录中,则用户只需转到example.com/uploads/malicious.php
即可执行该文件并在您的服务器上运行任意PHP代码 .永远不要将任意上传的文件存储在任何地方,始终将它们存储在只有您的应用程序可以访问它们的地方 .
仅允许特定进程访问文件 . 如果它应该是图像文件,则只允许读取图像的脚本并调整它们的大小以直接访问文件 . 如果此脚本在读取文件时遇到问题,则可能不是图像文件,标记它和/或丢弃它 . 其他文件类型也是如此 . 如果该文件应该可由其他用户下载,请创建一个脚本,该文件为该文件提供下载,并且不对其进行任何其他操作 .
如果您不知道要处理的文件类型,请自行检测文件的MIME类型和/或尝试让特定进程打开文件(例如,让图像调整大小的过程尝试调整假定图像的大小) . 这里也要小心,如果该过程中存在漏洞,则恶意制作的文件可能会利用它,这可能导致安全漏洞(此类攻击最常见的例子是Adobe的PDF阅读器) .
解决您的具体问题:
不 . 如果你没有做任何事情,只是将数据存储在临时文件夹中的文件中是没有风险的那些数据 . 数据只是数据,无论其内容如何 . 如果你正在尝试执行数据,或者程序正在解析数据,如果程序包含解析缺陷,可能会被恶意数据欺骗做出意外事情,那么这样做是有风险的 .
当然,在磁盘上放置任何类型的恶意数据比在任何地方都没有恶意数据风险更大 . 你永远不会知道谁会来并用它做点什么 . 因此,如果未通过验证,您应该验证所有上传的数据并尽快将其丢弃 .
这取决于你下载的具体内容 . 一个URL最多会产生一个数据块 . 如果您正在解析该数据并且正在根据您的问题初始blob下载更多URL的内容 . 不要这样做 . 但即使你这样做了,那么你还有一个充满东西的临时目录 . 再说一次,如果你没有对那些东西做任何危险,这并不危险 .
1个简单的场景是:如果您使用上传界面,对上传文件的类型没有限制,则攻击者可以上传带有恶意代码的PHP或.NET文件,这可能导致服务器泄露 .
参考:http://www.acunetix.com/websitesecurity/upload-forms-threat.htm以上链接讨论了常见问题
也请参考:http://php.net/manual/en/features.file-upload.php