【发布时间】:2012-04-12 23:37:09
【问题描述】:
我希望允许网站 (PHP) 的注册用户上传文件(文档),这些文件将公开供下载。 在这种情况下,我保留文件的原始名称是一个漏洞吗? 如果是一个,我想知道为什么,以及如何摆脱它。
【问题讨论】:
标签: php security file-upload filenames
我希望允许网站 (PHP) 的注册用户上传文件(文档),这些文件将公开供下载。 在这种情况下,我保留文件的原始名称是一个漏洞吗? 如果是一个,我想知道为什么,以及如何摆脱它。
【问题讨论】:
标签: php security file-upload filenames
虽然这是一个老问题,但在查找“安全文件名”时,它在搜索结果列表中的排名出奇地高,因此我想扩展现有答案:
是的,几乎可以肯定这是一个漏洞。
如果您尝试使用原始文件名存储文件,您可能会遇到几个问题:
.htaccess 的文件,告诉网络服务器将所有 .gif 文件解析为 PHP,然后上传一个带有 <?php /* ... */ ?> GIF 注释的 .gif 文件,会发生什么?../。如果用户上传一个名为“名称”../../../../../etc/cron.d/foo 的文件会怎样? (这个特殊的例子应该被系统权限捕获,但是你知道你的系统读取配置文件的所有位置吗?)
www-data)配置错误并且有一个shell,那么../../../../../home/www-data/.ssh/authorized_keys 怎么样? (同样,这个特殊的例子应该被 SSH 本身(并且可能文件夹不存在)保护起来,因为 authorized_keys 文件需要非常特殊的文件权限;但是如果您的系统设置为默认情况下限制文件权限(棘手!),那么这不会是问题。)x00 字节或控制字符。系统程序可能无法按预期响应这些 - 例如一个简单的ls -al | cat(不是我知道你为什么要执行它,而是一个更复杂的脚本可能包含一个最终归结为这个的序列)可能会执行命令。.php 结尾,并在有人尝试下载文件时执行。 (不要try blacklisting extensions。)处理此问题的方法是自己滚动文件名(例如,文件内容或原始文件名上的md5())。如果您绝对必须尽最大努力允许原始文件名,请将文件扩展名列入白名单,mime-type 检查文件,然后将文件列入白名单 字符可用于文件名。
或者,您可以在存储文件时自己滚动文件名,并在人们用来下载文件的 URL 中使用(尽管如果这是一个文件服务脚本,您应该避免无论如何,让人们在此处指定文件名,因此没有人下载您的../../../../../etc/passwd 或其他感兴趣的文件),但将原始文件名保存在数据库中以在某处显示。在这种情况下,您只需要担心 SQL 注入和 XSS,这是其他答案已经涵盖的基础。
【讨论】:
文件的名称可能会泄露潜在的敏感信息。一些公司/人对文档使用不同的命名约定,因此您最终可能会得到:
我想你明白了,你可能会想到人们在他们的文件名中使用的一些其他信息。
根据您的网站是什么,这可能会成为一个问题(考虑 wikileaks 是否发布了在文件名中包含原始来源的泄露文档)。
如果您决定隐藏文件名,则必须考虑有人将可执行文件作为文档提交的问题,以及如何确保人们知道他们正在下载的内容。
【讨论】:
这取决于您存储文件名的位置。如果您将名称存储在数据库中,在严格类型的变量中,然后在将其显示在网页上之前进行 HTML 编码,不会有任何问题。
【讨论】: