mrm*_*man 9 php file-upload temporary-files
当用户上传文件时,随机将其替换为另一个用户的上传,我最终将问题追溯到PHP并重新使用tmp文件名.有没有办法来解决这个问题?有没有办法制作更好的随机名称?它随着时间的推移似乎会降级,因为随机文件名种子变得越来越弱?这是在PHP 5.2.8和FreeBSD 7.0上
这是一个日志,显示了如何使用相同的tmp文件名并被另一个上传覆盖:http://pastebin.com/m65790440
任何帮助是极大的赞赏.我一直试图解决这个问题超过4个月,并且随着时间的推移变得更糟.谢谢.
编辑:请记住,这不是PHP代码问题,这是在它到达任何PHP代码之前发生的,通过$ _FILES ['name'] ['tmp_name']收到的文件在收到并且被跟踪时是不正确的在它到达上传处理脚本之前,它被其他人的上传覆盖了
在 FreeBSD 7 的 libc 实现中将相关代码追踪到_gettemp之后,我不清楚文件的内容是如何tmp_name无效的。(要跟踪它,您可以下载 PHP 5.2.8 的副本并阅读内嵌main/rfc1867.c1018 行调用main/php_open_temporary_file.c,该函数从第 227 行开始,它在第 97 行开始的函数中执行主要工作,然而,它本质上是只是系统上 mkstemp 的一个包装器,它可以在第66 行(链接)的FreeBSD libc 实现中找到,它使用_gettemp(与上面相同)来实际生成随机文件名。但是mkstemp 的联机帮助页在 BUGS 部分中提到该arc4random()函数不可重入。它可能有 2 个同时请求进入关键代码部分并返回相同的内容tmp_name- 我对 Apache 如何与 mod_php 或 php-cgi 一起工作知之甚少,无法在那里发表评论(尽管使用 FastCGI/php-cgi 可能有效 - 我可以'目前无法对此发表评论)。
但是,针对最简单的解决方案,如果您没有完全体验到文件tmp_name本身无效,而是与其他上传的文件发生冲突(例如,如果使用 tmp_name 的文件名部分作为存储文件名中唯一性的唯一来源),由于生日悖论,您可能会面临碰撞。在另一个问题中,您提到要移动大约 5,000,000 个文件,在另一个问题中,您提到每天接收 30-40k 次上传。这让我觉得这是生日悖论碰撞的主要情况。该mktemp的手册页提到(如果像 PHP 那样使用六个“X”)有 56,800,235,584 个可能的文件名(62 ** 6 或 62 ** n 其中 n = 'X' 的数量等)。但是,鉴于您有超过 500 万个文件,碰撞的概率大约为 100%(另一个启发式表明您已经经历了大约 220 次碰撞,如果 ((files*(files-1)) /2)/(62**6) 意味着任何东西,其中文件 = 5,000,000)。如果这是您面临的问题(可能,如果没有为生成的上传文件名添加更多熵),您可以尝试类似的方法move_uploaded_file($file['tmp_name'], UPLOADS.sha1(mt_rand().$file['tmp_name']).strrchr($file['name'], '.'))- 为随机文件名添加更多随机性,防止冲突。另一种方法是在第 134 行再添加两个“X”main/php_open_temporary_file.c并重新编译。
| 归档时间: |
|
| 查看次数: |
4879 次 |
| 最近记录: |