php硬编码,PHP 使用硬编码检测文件 MIME

很多系统重需要使用到文件上传功能,如果有人故意将文件的后缀名改成符合要求的文件,比如.exe改成.jpg文件,这样可以上传文件,但是却有别攻击的风险。我们可以根据文件的硬编码来检测文件的MIME类型,这样文件的类别就不会出错。

主要思路是读取文件头的钱4个字节,参考文件硬编码,进行匹对:

namespace App\Services\Tools;

use App\Services\BaseService;

class FileService extends BaseService

{

public function fileCheck($file)

{

$mime_type = null;

$file_ext = null;

$origin_ext = null;

if(is_uploaded_file($file)) {

$mime_type = $this->getFileMIME($file);

$file_ext = $this->getFileExt($mime_type);

$ext = $file->getClientOriginalExtension();// 获取文件的扩展名

if($file_ext == "type_error"){

throw new Exception('文件类型不支持,请重试');

}

$origin_ext = $this->fileExtCheck($file_ext, $ext); // 对文件扩展名验证

}else{

$_FILES ['temp'] ['error'] = 6;

}

$this->fileUploadCheck($_FILES); // 文件上传验证

if(!empty($mime_type)){

return ["mime"=>$mime_type,"ext"=>$origin_ext];

}else{

throw new InternalServerError(50513);

}

}

// 读取文件获取MIME_TYPE

function getFileMIME($filename)

{

$file = fopen($filename, "rb");

$bytes4 = fread($file, 4);

fclose($file);

$strInfo = @unpack("C4chars", $bytes4);

$typeCode = dechex($strInfo ['chars1']) .

dechex($strInfo ['chars2']) .

dechex($strInfo ['chars3']) .

dechex($strInfo ['chars4']); //把十进制转换为十六进制。

switch ($typeCode) //硬编码值查表

{

case "ffd8ffe0" :

case "ffd8ffe1" :

case "ffd8ffe2" :

$type = 'image/jpeg; charset=binary';

break;

case "89504e47" :

$type = 'image/png; charset=binary';

break;

case "47494638" :

$type = 'image/gif; charset=binary';

break;

case "504B0304" :

$type = 'application/zip; charset=binary';

break;

case "25504446" :

$type = 'application/pdf; charset=binary';

break;

case "5A5753" :

$type = 'application/swf; charset=binary';

break;

case "3c3f786d" :

$type = 'application/xml; charset=binary';

break;

case "3c68746d" :

$type = 'application/html; charset=binary';

break;

case "0000" :

$type = 'text/plain; charset=binary';

break;

case "2166756e" :

$type = 'application/x-javascript; charset=binary';

break;

default :

$type = 'application/octet-stream; charset=binary';

break;

}

return $type;

}

// 获取文件扩展名

function getFileExt($type) {

switch ($type) {

case "image/jpeg; charset=binary" :

$extType = "jpeg|jpg|jpe";

break;

case "image/png; charset=binary" :

$extType = "png";

break;

case "image/gif; charset=binary" :

$extType = "gif";

break;

case "application/zip; charset=binary" :

$extType = "zip";

break;

case "application/pdf; charset=binary" :

$extType = "pdf";

break;

case "application/swf; charset=binary" :

$extType = "swf";

break;

case "application/xml; charset=binary" :

$extType = "xml";

break;

case "application/html; charset=binary" :

$extType = "html";

break;

case "text/plain; charset=binary" :

$extType = "txt";

break;

case "application/x-javascript; charset=binary" :

$extType = "js";

break;

default :

$extType = "type_error";

break;

}

return $extType;

}

// 文件扩展名验证

function fileExtCheck($muti_ext, $ext)

{

$muti_ext = explode('|',$muti_ext);

if(in_array($ext, $muti_ext)){

return $ext;

}else{

return current($muti_ext);

}

}

// 文件上传验证

function fileUploadCheck($file_error)

{

if ($file_error['temp']['error'] > 0) {

$error_mag = 'Error: ';

switch ($file_error['temp']['error']) {

case 1 :

$error_mag = $error_mag.'上传文件过大,请重试';

break;

case 2 :

$error_mag = $error_mag. '上传文件过大,请重试';

break;

case 3 :

$error_mag = $error_mag. '文件上传丢失,请重试';

break;

case 4 :

$error_mag = $error_mag. '无文件被上传,请重试';

break;

case 6 :

$error_mag = $error_mag. '文件类型不支持,请重试';

break;

case 7 :

$error_mag = $error_mag. '上传文件存储失败,请重试';

break;

}

throw new Exception($error_mag);

}

}

}

以上对 jpeg|jpg|jpe 、png、gif、zip、pdf、swf、xml、html、txt、js文件进行硬编码检测,其他的文件格式可以参考硬编码表添加就可以了。

本作品采用《CC 协议》,转载必须注明作者和本文链接

Ethan Smart & AI Algorithm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值