php判断上传文件,php判断上传文件文件类型的安全方法

在使用 php 进行文件的上传和存储时,很多人都会给文件进行重名命并保存到可写文件夹下,然后我们在其中一个失误的地方便是采用上传文件的扩展名作为判断文件类型的依据。

这样做其实与后门大开无异,举一个简单的例子,通过扩展名判断一般是字符串的截取判断,或者是使用$_FILE数组判断,然后如果用户上传的文件名为 image.php.png, image.png.php, image.php%****.png 之类的话,判断就会出错。

另外,$_FILES['type']可能被篡改。

下面是我判断文件名的方法:

读取文件头四个字节作为判断。

下面直接上代码

我实现的是仅支持word和pdf文件,且文件大小小于512kb:

$tmpname = $_FILES ['userfile'] ['tmp_name'];

if(is_uploaded_file($tmpname)) {

$mimetype = detectMIME($tmpname);

$tuozhanming = getFileExt($filename, $mimetype);

if($tuozhanming == "type_error"){

echo '仅支持word和pdf文件,且文件大小小于512kb:请重试';

exit();

}

}else{

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

}

if ($_FILES ['userfile'] ['error'] > 0) {

echo 'Problem: ';

switch ($_FILES ['userfile'] ['error']) {

case 1 :

echo '上传文件过大:请重试';

break;

case 2 :

echo '上传文件过大:请重试';

break;

case 3 :

echo '文件上传丢失:请重试';

break;

case 4 :

echo '无文件被上传:请重试';

break;

case 6 :

echo '仅支持word和pdf文件,且文件大小小于512kb:请重试';

break;

case 7 :

echo '上传文件存储失败:请重试';

break;

}

exit ();

}

//判断文件类型

//上传文件

$_FILES ['userfile'] ['name'] = time () . "." . $tuozhanming;

$upfile = '../uploads/' . $_FILES ['userfile'] ['name'];

if ( !move_uploaded_file ( $_FILES ['userfile'] ['tmp_name'], $upfile )) {

echo 'Problem: 文件移动失败';

exit ();

}

}

function detectMIME($filename) {

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

$finfo = finfo_open ( FILEINFO_MIME );

if (! $finfo) {

// 直接读取文件的前4个字节,根据硬编码判断

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

$bin = fread ( $file, 4 ); //只读文件头4字节

fclose ( $file );

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

//dechex() 函数把十进制转换为十六进制。

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

dechex ( $strInfo ['chars2'] ) .

dechex ( $strInfo ['chars3'] ) .

dechex ( $strInfo ['chars4'] );

$type = '';

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

{

case "504b34" :

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

break;

case "d0cf11e0" :

$type = 'application/vnd.ms-office; charset=binary';

break;

case "25504446" :

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

break;

default :

$type = 'application/vnd.ms-office; charset=binary';

break;

}

} else {

//finfo_file return information of a file

$type = finfo_file ( $finfo, $filename );

}

return $type;

function getFileExt($filename, $type) {

switch ($type) {

case "application/zip; charset=binary" :

$extType = "docx";

break;

case "application/vnd.ms-office; charset=binary" :

$extType = "doc";

break;

case "application/msword; charset=binary" :

$extType = "doc";

break;

case "application/pdf; charset=binary" :

$extType = "pdf";

break;

default :

$extType = "type_error";

break;

}

return $extType;

}

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:php中文网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值