PHP图像上传安全检查列表

use*_*ksa 61 php security upload

我正在编写一个脚本来将图像上传到我的应用程序.以下安全步骤是否足以使应用程序从脚本端安全?

  • 使用.httaccess禁止PHP在上传文件夹中运行.
  • 如果文件名包含字符串"php",则不允许上传.
  • 仅允许扩展名:jpg,jpeg,gif和png.
  • 仅允许图像文件类型.
  • 禁止具有两种文件类型的图像.
  • 更改图像名称.
  • 上传到子目录而不是根目录.

这是我的脚本:

 $filename=$_FILES['my_files']['name'];
 $filetype=$_FILES['my_files']['type'];
 $filename = strtolower($filename);
 $filetype = strtolower($filetype);

 //check if contain php and kill it 
 $pos = strpos($filename,'php');
 if(!($pos === false)) {
  die('error');
 }




 //get the file ext

 $file_ext = strrchr($filename, '.');


 //check if its allowed or not
 $whitelist = array(".jpg",".jpeg",".gif",".png"); 
 if (!(in_array($file_ext, $whitelist))) {
    die('not allowed extension,please upload images only');
 }


 //check upload type
 $pos = strpos($filetype,'image');
 if($pos === false) {
  die('error 1');
 }
 $imageinfo = getimagesize($_FILES['my_files']['tmp_name']);
 if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime']      != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
   die('error 2');
 }
//check double file type (image with comment)
if(substr_count($filetype, '/')>1){
die('error 3')
}

 // upload to upload direcory 
 $uploaddir = 'upload/'.date("Y-m-d").'/' ;

if (file_exists($uploaddir)) {  
} else {  
    mkdir( $uploaddir, 0777);  
}  
  //change the image name
 $uploadfile = $uploaddir . md5(basename($_FILES['my_files']['name'])).$file_ext;



  if (move_uploaded_file($_FILES['my_files']['tmp_name'], $uploadfile)) {
 echo "<img id=\"upload_id\" src=\"".$uploadfile."\"><br />";
  } else {
   echo "error";
  }
Run Code Online (Sandbox Code Playgroud)

欢迎任何新的提示:)

Hal*_*gür 33

使用GD(或Imagick)重新处理图像并保存处理后的图像.所有其他人对黑客来说都很有趣.

编辑:正如rr指出的那样,move_uploaded_file()用于任何上传.

延迟编辑:顺便说一句,您希望对上传文件夹非常严格.那些地方是许多漏洞发生的黑暗角落之一.这适用于任何类型的上载和任何编程语言/服务器.检查https://www.owasp.org/index.php/Unrestricted_File_Upload

  • 标记我的话:大多数时候,CPU是最冗余的资源.只需观看任何给定机器/服务器的图形(谷歌,Facebook等服务器除外).你会发现大部分时间都在那里撒粉.像SETI @ Home这样的项目试图利用那个空闲时间.无论如何,增加安全性的努力将是值得的. (7认同)
  • +1。如果*它是一个图像*并且包含有效的扩展名,我看不出列表中的任何检查(在问题中)如何有用。 (2认同)
  • 您愿意举“重新处理”的例子吗?可以用imagick(或更糟的GD)说吗? (2认同)
  • @ thorne51,我相信没有任何功能足以检查.所以根本不要检查,只需创建一个新图像.示例:PHP代码可以隐藏在图像的EXIF,XMP等部分中,并且函数/程序可能会失败(无意中或通过使用漏洞利用代码)来报告该代码. (2认同)

tan*_*jir 12

对于图像文件的安全性测试,我可以想到4级证券.他们将是:

  • 第1级:检查扩展名(扩展名文件以)结尾
  • 第2级:检查MIME类型 ($file_info = getimagesize($_FILES['image_file']; $file_mime = $file_info['mime'];)
  • 级别3:读取前100个字节并检查它们是否具有以下范围内的任何字节:ASCII 0-8,12-31(十进制).
  • 级别4:检查标题中的幻数(文件的前10-20个字节).你可以在这里找到一些文件头字节:http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Examples

注意:加载整个图像会很慢.


Rok*_*alj 7

XSS警告

还有一个非常重要的评论.不要在浏览器中提供/上传任何可以解释为HTML的内容.

由于文件位于您的域中,因此该HTML文档中包含的javascript将可以访问您的所有Cookie,从而实现某种XSS攻击.

攻击场景:

  1. 攻击者使用JS代码上传HTML文件,该代码将所有cookie发送到他的服务器.

  2. 攻击者通过邮件,PM或简单地通过他或任何其他站点上的iframe将链接发送给您的用户.

最安全的解决方案

使上传的内容仅在子域或另一个域上可用.这样就无法访问cookie.这也是谷歌的性能提示之一:

https://developers.google.com/speed/docs/best-practices/request#ServeFromCookielessDomain


rr.*_*rr. 6

您可能还想在$ _FILES ['my_files'] ['tmp_name']上运行"is_uploaded_file".请参见http://php.net/manual/en/function.is-uploaded-file.php


小智 6

在uploads目录中创建一个新的.htaccess文件并粘贴此代码:

php_flag engine 0
RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
Run Code Online (Sandbox Code Playgroud)

只需确保重命名你上传的文件+忘记检查类型,内容等


doc*_*doc 5

我将重复我在相关问题中发布的内容.

您可以使用Fileinfo函数(先前版本的PHP中的mime_content_type())检测内容类型.

旧版Mimetype扩展的PHP手册摘录,现在由Fileinfo替换:

此模块中的函数尝试通过查找文件中特定位置的某些魔术字节序列来猜测文件的内容类型和编码.虽然这不是一种防弹方法,但使用的启发式方法做得非常好.

getimagesize()也可以做得很好,但你执行的大多数其他检查都是无稽之谈.例如,为什么php文件名中不允许使用字符串.您不会在PHP脚本中包含图像文件,只是因为它的名称包含php字符串,不是吗?


在重新创建图像时,在大多数情况下,它将提高安全性......直到您使用的库不易受攻击.

那么哪个PHP扩展最适合安全的图像重新创建?我查了CVE详情网站.我认为适用的三重奏是那些扩展:

  1. GD(6个漏洞)
  2. ImageMagick(44个漏洞)
  3. Gmagick(12个漏洞)

从比较中我认为GD最适合,因为它具有最少的安全问题并且它们已经很老了.其中三个是关键,但ImagMagick和Gmagick表现不佳...... ImageMagick似乎非常错(至少在安全方面),所以我选择Gmagick作为第二选择.