是否应重命名上传的文件?

Nat*_*ate 5 php security file-upload

我一直在阅读PHP文件上传安全性,一些文章建议重命名文件.例如,OWASP文章Unrestricted File Upload 说:

建议使用算法来确定文件名.例如,文件名可以是文件名的MD5哈希值加上一天的日期.

如果用户上传名为的文件,Cake Recipe.doc是否真的有任何理由将其重命名为45706365b7d5b1f35

如果答案是肯定的,无论出于何种原因,那么如何跟踪原始文件名和扩展名?

Jac*_*b S 13

对于您的主要问题,重命名文件是一个好习惯,答案肯定是肯定的,特别是如果您要创建一个文件存储库形式,用户上传他们选择的文件(和文件名),原因如下:

  1. 安全性 - 如果您的应用程序编写得很糟糕,允许通过名称或直接访问来下载文件(这很可怕,但它确实发生了),对于用户来说,无论是恶意还是故意,都难以"猜测"这些名称的文件.
  2. 唯一性 - 两个不同的人上传同名文件的可能性非常高(即avatar.gif,readme.txt,video.avi等).使用唯一标识符可显着降低两个文件具有相同名称的可能性.
  3. 版本控制 - 使用唯一名称保存文档的多个"版本"要容易得多.它还避免了需要额外的代码来解析文件名以进行更改.一个简单的例子就是document.pdf到document(1).pdf,当你不低估用户为事物创建可怕名字的能力时会变得更加复杂.
  4. 长度 - 使用已知的文件名长度总是比使用未知的文件名长度更好.我总是可以知道(我的文件路径)+(X个字母)是一定的长度,其中(我的文件路径)+(随机用户文件名)是完全未知的.
  5. 操作系统 - 上面的长度在尝试将极随机/长文件名写入驱动器时也会产生问题.您必须考虑特殊字符,长度和修剪文件名的问题(用户可能无法接收工作文件,因为扩展已被修剪).
  6. 执行 - 操作系统很容易执行名为.exe,.php或(插入其他扩展名)的文件.没有扩展时很难.
  7. URL编码 - 确保名称是URL安全的.Cake Recipe.doc不是URL安全名称,并且可以在某些系统(服务器或浏览器端)/某些情况下,当名称应为urlencoded值时导致不一致.

至于存储信息,你通常会在数据库中执行此操作,这与您已经存在的需求没有什么不同,因为您需要一种方式来引用回文件(谁上传,名称是什么,偶尔存储它的位置,上传的时间,有时是大小).除了文件的用户名之外,您只需添加文件的实际存储名称即可.

OWASP建议并不错 - 使用文件名和时间戳(不是日期)将是最独特的.我更进一步,将microtime包含在时间戳中,并经常包含其他一些独特的信息,以便在同一时间范围内重复上传小文件 - 我还会存储上传日期这是针对md5冲突的附加保险,它在存储许多文件和多年的系统中具有更高的概率.你不可能在同一天使用文件名和microtime生成两个像md5s.一个例子是:

$filename = date('Ymd') . '_' . md5($uploaded_filename . microtime());
Run Code Online (Sandbox Code Playgroud)

我的2美分.