Php finfo 检测 php 文件为 jpeg
Php finfo detecting php file as a jpeg
我试着写一个上传表单,我希望用户只发送图像或 pdf 文件。为了检测 mime 类型,我使用 finfo
,但在这里举个例子很容易搞砸他
<?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
像许多工具或工具(例如 unix 上的 cmd file
)使用“魔术 table”来找出哪种文件就是它。 Look at those example
短版 finfo
在流中搜索一系列特定字节,如果找到,它 return 与这些数字关联的 mime 类型。
要欺骗它,您只需要在文件中包含这些字节...
它没有回答关于如何正确找出的问题...
这是获取图像文件扩展名的方法:
$path = $_FILES['image']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
这是 Html 代码:
<form action="" method="POST">
<input type="file" name="" id="" accept="application/pdf,image/jpeg">
<input type="submit" name="submit" value="">
</form>
为什么要使用 Finfo?
有几种提高文件安全性的方法;
图像最有效的方法是将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 年代的色情作品,你才能确定。
一些有用的链接:
- http://www.php.net/manual/en/function.exif-imagetype.php
- PHP check if file is an image
我试着写一个上传表单,我希望用户只发送图像或 pdf 文件。为了检测 mime 类型,我使用 finfo
,但在这里举个例子很容易搞砸他
<?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
像许多工具或工具(例如 unix 上的 cmd file
)使用“魔术 table”来找出哪种文件就是它。 Look at those example
短版 finfo
在流中搜索一系列特定字节,如果找到,它 return 与这些数字关联的 mime 类型。
要欺骗它,您只需要在文件中包含这些字节...
它没有回答关于如何正确找出的问题...
这是获取图像文件扩展名的方法:
$path = $_FILES['image']['name'];
$ext = pathinfo($path, PATHINFO_EXTENSION);
这是 Html 代码:
<form action="" method="POST">
<input type="file" name="" id="" accept="application/pdf,image/jpeg">
<input type="submit" name="submit" value="">
</form>
为什么要使用 Finfo?
有几种提高文件安全性的方法;
图像最有效的方法是将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 年代的色情作品,你才能确定。
一些有用的链接:
- http://www.php.net/manual/en/function.exif-imagetype.php
- PHP check if file is an image