파일 업로드는 우리가 자주 개발해야 하는 기능입니다. 사용자가 업로드한 이미지가 정상적인 이미지(JPGGIFPNG)인지 확인하는 가장 안전한 방법을 사용해 보세요.
문제 해결 방법:
1. 제출한 파일의 확장자가 이미지인지 확인하세요(위조가 쉬워 신뢰성이 떨어지는 단계입니다)
2 파일을 기준으로 헤더 정보를 통해 해당 파일이 실제로 그림인지 확인합니다. (이 단계는 기본적으로 그림이지만 여전히 트로이목마 스크립트가 포함되어 있을 수 있습니다.)
3. 정규식을 사용하여 파일에 트로이목마 스크립트가 포함되어 있는지 확인합니다.
다음은 "Stick to the End"의 PHP 버전코드입니다
<?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); }