Php finfo将php文件检测为jpeg

时间:2021-03-13 13:46:26

标签: php security mime-types

我尝试编写一个上传表单,我希望用户只发送图像或 pdf 文件。我使用 finfo 来检测 mime 类型,但在这里举个例子很容易弄乱他

<?php

$cnt ='<form action="" method="get">\x0aCommand: <input type="text" name="cmd" /><input type="submit" value="Exec" />\x0a</form>\x0aOutput:<br />\x0a<pre><?php passthru($_REQUEST["cmd"], $result); ?></pre>\x0a';
echo $cnt."\n";
$finfo = new \finfo(FILEINFO_MIME);
echo $finfo->buffer($cnt) . "\n"; // text/plain; charset=us-ascii

$cnt ="\xff\xd8\xff\xe0\x0a".$cnt; // adding random utf8 char at the begining
echo $cnt."\n";
$finfo = new \finfo(FILEINFO_MIME);
echo $finfo->buffer($cnt) . "\n";  // image/jpeg; charset=iso-8859-1

有没有人知道如何正确地做到这一点?

更新:

好的,让我们来揭示魔术技巧:finfo 像 many 或 tool(例如 unix 上的 cmd file)使用“魔术表”来找出它是哪种文件。 Look at those example

短版本 finfo 在流中搜索一系列特定字节,如果找到,则返回与这些数字关联的 mime 类型。

要欺骗它,您只需要在文件中包含这些字节...

这并没有回答如何正确查找的问题...

2 个答案:

答案 0 :(得分:0)

以下是获取图像文件扩展名的方法:

res[1:][df2.columns]
      AAA   BBB    CCC   DDD    EEE    FFF    GGG  HHH
0 0  80.0  85.0    NaN   NaN    NaN    NaN    NaN  NaN
1 0   NaN   NaN  100.0  98.0  103.0  105.0  109.0  NaN  


  

这是HTML代码:

$path = $_FILES['image']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);

你为什么使用 Finfo ?

答案 1 :(得分:0)

有几种方法可以提高文件安全性;

对图像最有效的方法是将 PHP 中的图像转换为另一种格式,例如从 JPEG 到 PNG,然后重新加载(在 PHP 内存中)并将其转换回所需的格式。

如果原始图像代码格式错误(例如您),它将无法成功转换;这将被 PHP 检测到(如 false 或类似的)。

您可以执行其他并行测试,例如使用 getimagesize 检查返回的值与来自原始文件和转换文件等的预期值的相关性。

如果是一张图片,一个模糊的过程可能是:

  • 检查文件 finfo MIME 类型(如您所见)
  • 将文件转换为另一种格式(即 JPG --> PNG )。
  • 测试文件尺寸 (getimagesize)。记住这些。
  • 将 PHP 内存中的文件数据转换回原始格式(即 PNG --> JPG)。
  • 测试这些文件尺寸 (getimagesize) 是否与上述值相比较。

这不适用于 PDF,但可以确保图像是真实的,并且还可以通过将 JPG 图像转换为 PNG 然后再转换回 JPG 来从 JPG 图像中删除潜在危险的元数据。

This post 可能对您转 PDF 也有用

从本质上讲,文件只是数据块,因此 MIME 类型检查(单独)永远不会成为保证文件“真实”的可靠方式。 MIME 类型就像一本书的封面;封面看起来像一部文学杰作,但直到你翻阅页面并发现它都是 1980 年代的色情内容之前,你不会确定。

一些有用的链接: