VeZ*_*oul 5 php json mime-types
我有一个脚本,可以从数据生成JSON文件.我有第二个脚本,从目录中读取文件只接受JSON文件并将其插入数据库.
问题是第二个脚本从我生成的文件中检测"application/octet-stream"MIME类型而不是 application/json
我不想允许application/octet-streamMIME类型,因为它可以是任何东西(出于安全原因:第二个脚本加载json目录中的所有文件(不仅是生成的文件)).
那么无论如何都要"设置"文件的MIME类型?
生成文件的代码:
if($r_handle = fopen($s_file_name, 'w+')){
fwrite($r_handle, json_encode($o_datas, JSON_HEX_QUOT | JSON_HEX_TAG));
fclose($r_handle);
return;
}
Run Code Online (Sandbox Code Playgroud)
读取JSON文件的代码:
$o_finfo = finfo_open(FILEINFO_MIME_TYPE);
$a_mimes =& get_mimes();
if(is_dir($s_dir) && $r_handle = opendir($s_dir)){
while($s_file = readdir($r_handle)){
$s_file_path = $s_dir.$s_file;
$s_mime = finfo_file($o_finfo, $s_file_path);
if(!in_array($s_file, array('.', '..')) && in_array($s_mime, $a_mimes['json'])){
// Some code
}
}
}
Run Code Online (Sandbox Code Playgroud)
fileinfo扩展(与file Unix 命令类似的工具)基本上搜索数据库中定义的签名(称为“magic”)。如果我没记错的话,PHP 的魔法数据库当前已编译到扩展二进制文件中,因此您无法查看它,但您的系统中可能会有一个类似的数据库。我有 Apache 的 at C:\Apache24\conf.magic,这是 JPEG 的条目:
# JPEG images
0 beshort 0xffd8 image/jpeg
Run Code Online (Sandbox Code Playgroud)
任何开头的0xffd8都是图片。完毕!

我不是特别熟悉这种格式,但它似乎根本不寻找JSON。而且,正如您可能已经猜到的那样,整体实用程序绝不是安全功能。它只是一个帮助工具来确定文件可能包含的内容。例如,如果您从损坏的磁盘中恢复了没有扩展名的文件,这将非常方便。
MIME 类型很酷。你设置了application/json,每个人都知道它是 JSON。简单明了,不是吗?只有两个警告:
文件系统(其中许多实际上是在 MIME 类型之前发明的)存储许多文件属性(名称、上次修改日期、权限,有时甚至是图标...),但不存储 MIME 类型。(当然,可能有一些学术文件系统可以做到这一点,但 FAT32、NTFS、ext4... 则不然)。它通常不会添加有价值的信息,它是另一个保持更新的令牌,并且特别不可移植(将文件复制到拇指驱动器,它们就会消失)。
它仍然不是一个安全功能。如果我可以伪造文件内容,那么什么可以阻止我伪造 MIME 类型?
所以,你可以做什么?最好的选择是:什么都不做。
只需将文件解析为 JSON 并检测是否失败。无论如何你都需要这样做,它会告诉你需要做的一切。JSON 只是纯文本数据。也许添加一些检查以防止非常大的文件(同样,您应该在文件上传中执行此操作)并添加检查,$depth但仅此而已。
if (json_decode($s_file_path, true, 32)!==null || json_last_error()!==JSON_ERROR_NONE) {
// Valid JSON
}
Run Code Online (Sandbox Code Playgroud)