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('jpg','gif','png'); //上传后存放的路径 $uploadfile = './data/' . basename($_FILES['userfile']['name']); //获取文件的扩展名 $finfo = new SplFileInfo($_FILES['userfile']['name']); $extName=$finfo->getExtension(); //第一道关卡,简单过滤非法文件。 if(!in_array($extName,$imageType)){ exit('只能上传gif、png和jpg的图片'); } //依据文件头信息检查图片的真实类型 //1 IMAGETYPE_GIF //2 IMAGETYPE_JPEG //3 IMAGETYPE_PNG $realType=exif_imagetype($_FILES['userfile']['tmp_name']); if( 1 == $realType || 2 ==$realType || 3 ==$realType){ //开始检查是否存在木马代码 $safe=is_safe($_FILES['userfile']['tmp_name']); if(!$safe){ exit ('图片包含木马,禁止上传!'); } if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { echo "文件上传成功.\n"; } else { echo "上传失败!\n"; } }else{ exit ('只能上传gif、png和jpg的图片'); } function is_safe($fileurl) { $handle = fopen($fileurl, 'rb'); $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); }