安全文件上传及其验证

4

我接收视频上传和图像上传:

我的环境: LAMP

编辑: 我将允许远程上传和POST视频上传

编辑2: 我得到的文件将被重命名,我不会存储原始文件名。

  1. 首先,我使用 $_FILES 检查MIME类型。

  2. 其次,如果函数存在,则使用finfo_file检查MIME类型 (PHP 5.3) 或者使用shell命令file。

  3. 如果文件通过了上述检查,就将其移到公共目录中。

我的问题是这个设置安全吗?还有什么可以改进的地方吗?昨天我整天都在阅读,对我来说似乎足够了,但谁知道呢 :)

当涉及编码和安全性时,我是一个新手 :-)


应跳过第一步。 - dqhendricks
2个回答

1
我还可以推荐以下内容:
  1. is_uploaded_file函数返回TRUE,如果由filename指定的文件是通过HTTP POST上传的。这对于确保恶意用户没有试图欺骗脚本在不应该工作的文件上工作非常有用—例如,/etc/passwd。如果存在任何可能将上传文件的内容透露给用户甚至同一系统上的其他用户的情况,此类检查尤其重要。

  2. basename()函数用于获取仅文件名,例如basename(c:/fakepath/something.avi); // 将返回something.avi,因为某些人尝试通过给出类似目录的文件名来欺骗计算机。

有关basename()的更多信息:

当您上传文件时,您希望将文件移动到所需的目录下,例如在/uploads/文件夹下,但是恶意用户可以将文件命名为something/hello.jpg,然后当您使用move_uploaded_file($source,$destionation)移动文件时,您的$destination将会是/uploads/something/hello.jpg,这会导致问题。为确保您只获得正确的文件名,您需要使用basename()函数,该函数返回hello.jpg等。

$file_name = basename($_FILES["upload_ctrl"]["name"]);
if(!move_uploaded_file($_FILES["upload_ctrl"]["tmp_name"],"uploads/".$file_name))
    echo "Opps I cannot upload the file";

关于basename的使用,请访问此处:http://php.net/manual/en/function.basename.php


啊,我忘了说我会允许一些用户组上传远程文件。至于basename,我不明白你的意思,我看了php.net,但仍然不理解它 :) - Klob
basename()函数提取文件名而不包含任何额外的路径。 - ComFreek
抱歉再次询问,当我检查 $_FILES[tmp_name] 时,它会给出文件名已重命名的目录。[tmp_name] => /var/www/vhosts/domain.com/tmp/p2A32.tmp这是否可以被利用?因为PHP已经重命名了文件,我不明白basename如何帮助我。 - Klob
这是针对 tmp_name 的,但如果您想使用原始名称存储文件怎么办?然后您将从用户那里获取带有欺骗性的 file_name。PHP将在脚本处理期间存储临时文件及其元数据,例如文件名,文件类型等,但在此之后它们将被删除。当您想要将文件与其原始名称一起存储时,basename() 是很有用的。 - Tarik
好的,我现在明白你的意思了,但是文件会被重命名、编码/调整大小并附带唯一的ID。如果没有更多的答案,我会标记你的回答,谢谢 :-) - Klob

1
只要您使用自己的文件名和扩展名进行重命名,并且在应用程序代码中没有包含类型漏洞(例如:include($_GET['whatever']);),这就相当不错了。您还需要确保服务器堆栈上的所有内容都是最新版本(特别是处理图像/视频的任何内容)。
其他人建议包括一个文件服务脚本,该脚本输出文件,而不是将文件保存在公共文件夹中并直接引用src属性中的文件。有些人还建议对所有内容进行病毒扫描。

1
以下是一些可能有帮助的进一步意见:https://dev59.com/a1jUa4cB1Zd3GeqPQl7L - dqhendricks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接