我想允许一个网站(PHP)的注册用户上传文件(文档),这将是公开下载。 在这种情况下,是我把文件的原始名称漏洞的事实呢? 如果它是一个,我想知道为什么,以及如何摆脱它。
Answer 1:
这取决于你在哪里保存的文件名。 如果您在数据库中存储的名称,在严格类型的变量,那么HTML编码,你在网页上显示它之前,不会有任何问题。
Answer 2:
这些文件的名称可以揭示潜在的敏感信息。 有些公司/人使用的文件不同的命名规则,所以你可能最终得到:
- 作者姓名(法院阶john.smith.doc)
- 公司名称(敏感信息,enterprisename.doc)
- 文件创建日期(letter.2012-03-29.pdf)
我想你的时候,你大概能想到的人在他们的文件名中使用的一些其他信息。
根据您的网站是关于什么的,这可能成为一个问题(考虑,如果维基解密公布的泄密文件的某处有文件名中的原始源)。
如果你决定要隐藏的文件名,你必须考虑人的问题提交一个可执行的文件,以及如何确保人们知道他们正在下载的内容。
Answer 3:
尽管这是一个老问题,它寻找“安全文件名”时,搜索结果列表中的高得惊人,所以我想在现有的答案展开:
是的,这是几乎可以肯定的一个漏洞。
还有,如果你尝试使用其原文件名保存文件时可能会遇到一些可能出现的问题:
- 文件名可能是保留或特殊文件名。 如果用户上传一个文件称为会发生什么
.htaccess
,告诉服务器无法解析所有.gif
文件作为PHP,然后上载.gif
文件用的GIF评论<?php /* ... */ ?>
? - 文件名可能包含
../
。 如果用户上传的“名”文件会发生什么../../../../../etc/cron.d/foo
? (这个特殊的例子应该由系统权限被抓住了,但你知道你的系统从读取配置文件中的所有位置吗?)- 如果Web服务器运行的用户(姑且称之为
www-data
)配置错误和具有壳,怎么样../../../../../home/www-data/.ssh/authorized_keys
? (同样,这个特殊的例子应该对通过SSH本身(也可能是文件夹不存在)把守,因为authorized_keys
文件需要非常特殊的文件权限;但如果你的系统设置给默认限制性的文件权限(技巧)! ,那么这将不会是问题。)
- 如果Web服务器运行的用户(姑且称之为
- 文件名可以包含
x00
字节,或控制字符。 系统程序可能无法将这些响应预期-例如,一个简单的ls -al | cat
ls -al | cat
(不,我知道为什么你要来执行,但更复杂的脚本可能包含最终归结为一个序列)可能会执行命令。 - 文件名可能结束在
.php
,一旦有人试图下载的文件来执行。 (不要尝试黑名单的扩展 。)
处理这个问题的方法是自己滚动的文件名(如md5()
上的文件内容或原始文件名)。 如果你绝对必须允许原文件名最好的你的能力, 白名单文件扩展名,MIME类型检查文件和白名单什么字符可以在文件名中使用。
或者,你可以自己滚动文件名时您存储文件,并在人们使用下载的文件(URL中使用,虽然如果这是一个文件服务脚本,你应该避免让人们在这里指定的文件名,反正,所以没有一个下载您../../../../../etc/passwd
或感兴趣的其他文件),但保存在数据库中显示的地方原来的文件名。 在这种情况下,你只有SQL注入和XSS担心,这是理由是其他的答案已经涵盖了。
文章来源: PHP File upload security - keeping the original file name