2

If this is a newby question, forgive me. I have coded a php file uploader. After hearing that hackers could attatch/disguise code to images to infect sites, I got an idea to solve that problem. To convert the upload image to another file format (png) and then to another (jpg) with 70% quality. This caused the malware to become corrupted. The problem is, this total conversion process takes a about 1 minute at top speed. The service I'm making needs to be quick to handle the file uploads so that the users can go about the work. How can I speed up this process? The upload code is below (important variables are blanked).

// upload the file
$status = "...recieving the file...";
move_uploaded_file($_FILES["file"]["tmp_name"], "$folder" . $_FILES["file"]["name"]);
$status = "...processing the file...";

// convert the file to destroy viruses
$filename21 = "$folder" . $_FILES["file"]["name"];
imagepng(imagecreatefromstring(file_get_contents($filename21)), "$folder"."debug.".$picture_newname.".png");
$imageTmp=imagecreatefrompng("$folder"."debug.".$picture_newname.".png");
imagejpeg($imageTmp, "$folder".$picture_newname.".jpg", 90);
imagedestroy($imageTmp);

These are the steps it follows:

  1. Scan database for file with the same name
  2. if file with same name is found, rename the current upload
  3. receive the file
  4. "evaluate" the file (the double conversion process to protect the server)
  5. insert the info into the uploads database

If any other codes are needed (or if i should do some more timing) please let me know. Thanks in advance for your assistance.

4

2 回答 2

2

这是一个疯狂的想法。您不仅会在图像格式之间转换时占用服务器,还会降低每个上传图像的质量。

我会推荐一种不同的方法

  1. 上传文件时,使用 PHP 的getimagesize()函数检查图像。如果此函数返回FALSE(或意外的图像类型,或奇怪的尺寸等),则文件已损坏并且可以删除。

  2. 使用exiftool或类似工具从上传的文件中删除所有元数据,然后再将其存储在服务器上。这样您就可以确保文件只包含图像数据。

  3. 也许您可以在使用它将文件保存在服务器上之前检查该值$_FILES["file"]["name"]是否不包含任何鬼鬼祟祟的东西。../../

于 2014-02-07T03:48:00.323 回答
1

由于 DoS 攻击,出于安全目的实施双重转换是完全糟糕的主意。速度和安全性之间的平衡解决方案必须包含:

  1. 检查 MIME 类型。
  2. 检查文件扩展名。
  3. 检查文件大小。(强烈推荐)
  4. 检查图像尺寸。(可选,取决于应用要求)

像这样的东西:

$allowable_types = array(
    'png'  => 'image/png',
    'jpeg' => 'image/jpeg',
    'gif'  => 'image/gif'
);
$max_file_size = 10240; // 10K limit example

$finfo = new finfo(FILEINFO_MIME_TYPE);
$type  = $finfo->file($_FILES['name']['tmp_name']);
$size  = filesize($_FILES['name']['tmp_name']);
$info  = pathinfo($_FILES['name']['tmp_name']); 

if (isset($allowable_types[$info['extension']])
    and $type === $allowable_types[$info['extension']] 
    and $size <= $max_file_size
) {
    // check image size if your app require this
    move_uploaded_file($_FILES['name']['tmp_name'], $destination);
}

更新

我不建议$_FILES['file']['name']在目标路径中使用或扫描整个目录以获得相同的名称。因为一些安全漏洞和性能下降。更好的解决方案是为每个图像生成唯一的名称:

$new_name = uniquid() . '.' . $info['extension'];
$destination = $upload_path . $new_name;
于 2014-02-07T04:10:23.647 回答