Home  >  Article  >  Backend Development  >  Determine whether the picture uploaded by the user is a normal picture

Determine whether the picture uploaded by the user is a normal picture

巴扎黑
巴扎黑Original
2016-11-11 13:35:011366browse

File uploading is a function that we often need to develop. Try to use the safest way to determine whether the image uploaded by the user is a normal image (JPGGIFPNG).

Problem-solving ideas:
1. Check whether the extension of the submitted file is an image (this step is easy to forge, so it is unreliable)
2. Check whether the file is really an image based on the header information of the file (this The first step is basically a picture, but it may still contain a Trojan script)
3. Use regular expressions to check whether the file contains a Trojan script

The following is the PHP version code of "Stick to the End"

<?php
//允许的图片类型
$imageType = array(&#39;jpg&#39;,&#39;gif&#39;,&#39;png&#39;);
//上传后存放的路径
$uploadfile = &#39;./data/&#39; . basename($_FILES[&#39;userfile&#39;][&#39;name&#39;]);
//获取文件的扩展名
$finfo = new SplFileInfo($_FILES[&#39;userfile&#39;][&#39;name&#39;]);
$extName=$finfo->getExtension();
//第一道关卡,简单过滤非法文件。
if(!in_array($extName,$imageType)){
    exit(&#39;只能上传gif、png和jpg的图片&#39;);
}
//依据文件头信息检查图片的真实类型
//1 IMAGETYPE_GIF 
//2 IMAGETYPE_JPEG 
//3 IMAGETYPE_PNG 
$realType=exif_imagetype($_FILES[&#39;userfile&#39;][&#39;tmp_name&#39;]);
if( 1 == $realType || 2 ==$realType || 3 ==$realType){
    //开始检查是否存在木马代码
    $safe=is_safe($_FILES[&#39;userfile&#39;][&#39;tmp_name&#39;]);
    if(!$safe){
        exit (&#39;图片包含木马,禁止上传!&#39;); 
    }
    if (move_uploaded_file($_FILES[&#39;userfile&#39;][&#39;tmp_name&#39;], $uploadfile)) {
        echo "文件上传成功.\n";
    } else {
        echo "上传失败!\n";
    }
}else{
    exit (&#39;只能上传gif、png和jpg的图片&#39;); 
}
function is_safe($fileurl) {
    $handle = fopen($fileurl, &#39;rb&#39;);
    $fileSize = filesize($fileurl);
    fseek($handle, 0);
    if ($fileSize > 512) { // 取头和尾
        $hexCode = bin2hex(fread($handle, 512));
        fseek($handle, $fileSize - 512);
        $hexCode .= bin2hex(fread($handle, 512));
    } else { // 取全部
        $hexCode = bin2hex(fread($handle, $fileSize));
    }
    fclose($handle);
    /* 匹配16进制中的 <% ( ) %> */
    /* 匹配16进制中的 <? ( ) ?> */
    /* 匹配16进制中的 <script | /script> 大小写亦可*/
    //匹配表示有木马
    return !preg_match("/(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is", $hexCode);
}


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn