php - 上传的文件应该重命名吗?

标签 php security file-upload

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

It is recommended to use an algorithm to determine the filenames. For instance, a filename can be a MD5 hash of the name of file plus the date of the day.

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

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

最佳答案

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

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

至于存储信息,您通常会在数据库中执行此操作,这与您已有的需求没有什么不同,因为您需要一种方法来回溯文件(上传者、文件名、有时位置)存储,上传时间,有时大小)。除了文件的用户名之外,您只需将文件的实际存储名称添加到该文件中。

OWASP 的建议并不坏——使用文件名和时间戳(不是日期)在很大程度上是唯一的。我更进一步,包括带有时间戳的微时间,通常还有一些其他独特的信息,这样就不会在同一时间范围内重复上传一个小文件——我还存储了上传日期这是针对 md5 冲突的额外保险,这在存储许多文件和多年的系统中具有更高的可能性。您不太可能在同一天使用文件名和微时间生成两个类似 md5 的文件。一个例子是:

$filename = date('Ymd') . '_' . md5($uploaded_filename . microtime());

我的 2 美分。

关于php - 上传的文件应该重命名吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17865860/

相关文章:

php用汉字执行mysql查询,SQL语法错误

php - 使用 php 将 mysql 查询转换为 JSON 对象?

php - mySQL 数据库和 PHP 中的 URL 字符串

java - 如何降低 Java 8 中测试的 Java 安全设置

javascript - django 如何处理大文件(图像)上传 > 400MB

php - db2_fetch_assoc() 在迭代结果集的过程中失败

security - 如何提高客户端-服务器系统的安全性?

javascript - HTML5 文件上传进度 - 仅限客户端

android - 多部分实体 POST android

c - 我应该如何检查无限循环攻击中的任何 fork() ?