【问题标题】:Secure image upload with PHP?使用 PHP 安全上传图片?
【发布时间】:2012-09-18 23:37:45
【问题描述】:

我想从浏览器窗口上传图片到我的服务器。但是,上传字段对每个人都是可见的,所以我需要设置一些限制。我只找到了 w3schools 文件上传(从 w3fools.com 开始,我不相信它)。我希望限制是:

最大尺寸 2.5M

图像类型 jpg、jpeg、png、gif

所以这是 w3schools 提供的代码,但它实际上不会将文件保存在任何地方?我已经对其进行了一些修改以满足我的需要。

<?php
$allowedExts = array("jpg", "jpeg", "gif", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/jpeg"))
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 2500000)
&& in_array($extension, $allowedExts))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Error: " . $_FILES["file"]["error"] . "<br />";
    }
  else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Stored in: " . $_FILES["file"]["tmp_name"];
    }
  }
else
  {
  echo "Invalid file";
  }
?>

由于我不希望我的网站被黑客入侵,我想要一个安全的解决方案,有什么帮助吗?

编辑

代码甚至什么都不做。那我该怎么做呢?

【问题讨论】:

  • 我认为你应该看看stackoverflow.com/a/10271295/1226894它回答了你的问题
  • 由于您只接受图片,您也可以查看stackoverflow.com/a/10464964/1226894,它会告诉您如何最好地检测假图片
  • @Baba 我用了你提供的代码,带着我的狗出去了。当我回来时,我的 wordpress 网站被 !X!X HACKED BY RUSSIAN PEOPLE !X!X 和它下面的俄罗斯国旗所取代。我看了看图片上传,注意到上传文件夹下有一些奇怪的文件,在索引文件夹中有一个 hack.php,我会看一下。但是,该文件是与您的脚本一起上传的,我的网站被黑了。怎么样?
  • 这可能不是您网站中唯一的漏洞......您需要检查整个网站
  • @Baba 您的代码确实包含安全漏洞,但是我认为您不应该删除它,因为简化示例最适合大多数人(更易于阅读和理解) .根据服务器版本/配置,简单的空字符攻击可能足以跳过您的扩展检查,并且如果服务器配置为每个人都可以通过发送 HTTP 请求从任何目录执行任何 .php 文件......无需解释了。 永远不要相信任何用户输入,并使用可以处理任何二进制序列而不仅仅是纯文本的函数进行清理。或使用数据模板。

标签: php file-upload image-upload


【解决方案1】:
<?php

          $file_name   = $_FILES['file']['name'];
          $file_size   = $_FILES['file']['size'];
          $file_tmp    = $_FILES['file']['tmp_name'];
          $file_type   = $_FILES['file']['type'];

          /* variable array for store errors */
          $errors   = [];                   


          /* Check if file already exists in location file save */
          $file_dir  = "uploads";
          /** if folder not exists, then create it **/
          if (!file_exists($file_dir)) {
            mkdir($file_dir, 0777, true);
          }

          $file_target = $file_dir . $file_name;
          if (file_exists($file_target)) {
            //$errors[] = "Sorry, <strong>{$file_name}</strong> already exists.";
          }


             /* Check file size */
          if ($file_size > 2500000) {
            $errors[] = "Sorry, <strong>{$file_name}</strong> is too large. It size is {$file_size} > 2500000 bytes";
          }


          /* Check current file formats with file secure */
          $file_secure  = array('jpg', 'jpeg', 'png', 'gif');                   
          $file_current = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); /* (end(explode('.', $file_name) */

          if (in_array($file_current, $file_secure) === false) {
            $errors[] = "Sorry, <strong>{$file_current}</strong> extension not allowed";            
          }


          /* Check if Errors exist, then not upload. Or if Errors NOT exist, then try upload */
          if (!empty($errors)) {                            

            /* display error */                 
            foreach ($errors as $keyError => $valueError) {
              echo "$keyError = $valueError <br />";
            }

            echo "<br />";
            echo "<strong>{$file_name}</strong> could not uploaded. <hr />";                            

          } else {

            if (move_uploaded_file($file_tmp, $file_target)) {

              echo "Upload: "    . $file_name . "<br />";
              echo "Type: "      . $file_type . "<br />";
              echo "Size: "      . ($file_size / 1024) . " Kb<br />";
              echo "Stored in: " . $file_tmp;

            } else {

              echo "Invalid file";

            }

          }

?>

【讨论】:

    【解决方案2】:
    1. $ratio2) { $thumb_w=$new_w; $thumb_h=$old_y/$ratio1; } 其他 { $thumb_h=$new_h; $thumb_w=$old_x/$ratio2; }
          $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h);
      
          imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);
      
                  if(!strcmp("png",$ext))             imagepng($dst_img,$filename);       else            imagejpeg($dst_img,$filename); 
              imagegif($dst_img,$filename);
                  imagedestroy($dst_img);         imagedestroy($src_img);   }  }  if(!function_exists('getExtension'))    {       function
      
      获取扩展($str){ $i = strrpos($str,"."); if (!$i) { return ""; } $l = strlen($str) - $i; $ext = substr($str,$i+1,$l); 返回 $ext; } }
      $image=$_FILES["$imagename"]['name'];   if($image)      {  
          $filename = stripslashes($_FILES["$imagename"]['name']); 
          $extension = getExtension($filename);       $extension =
      
      strtolower($extension); if (($extension != "jpg") && ($extension != "jpeg") && ($extension != "png") && ($extension != "gif") && ($extension != "bmp")) {
              $obj->set_flash("Unknown extension...!");           header("Location: $filename ");             exit;       }       else        {
      
              $size=getimagesize($_FILES["$imagename"]['tmp_name']);
              $sizekb=filesize($_FILES["$imagename"]['tmp_name']);
      
              if ($sizekb > MAX_SIZE*1024)
              {
                  $obj->set_flash("You have exceeded the size limit...!");
                  header("Location: $filename");
                  exit;
              }
      
          $select_max = $obj->sql_query("select max($fieldname) as MaxID from  ".$tablename."");
                          if($action=="Add")          {
                  $Max = $select_max[0]['MaxID'];
                  $image_name = $Max + 1;
                  $new_name = $image_name.".".$extension;//the new name will be containing the full path where will be stored (images folder)
                  $$imagename = $new_name;//New Name of Image same as Image Field Name
                  $thumbfilename = $new_name;
                  $newname="$uploadpath/large/".$new_name;
      
                  $copied = copy($_FILES["$imagename"]['tmp_name'], $newname);
                  //we verify if the image has been uploaded, and print error instead
                  if (!$copied) 
                  { 
                      $obj->set_flash("Copy unsuccessfull...!");
                      header("Location: $filename");
                      exit;
                  }
                  else
                  {
                      $thumb_name="$uploadpath/thumb/".$thumbfilename;
                      $thumb=make_thumb($newname,$thumb_name,$WIDTH,$HEIGHT);
                  }           }           if($action=="Update")           {
      
                  $new_name=$ID.".".$extension;
                  $$imagename = $new_name;//New Name of Image same as Image Field Name
                  $newname = "$uploadpath/large/".$new_name;
                  $thumbfilename = $new_name;
                  $copied = copy($_FILES["$imagename"]['tmp_name'], $newname);
      
                  if (!$copied) 
                  {
                      $obj->set_flash("Copy unsuccessfull...!");
                      header("Location: $filename");
                      exit;
                  }
                  else
                  {
                      $thumb_name="$uploadpath/thumb/".$thumbfilename;
                      $thumb=make_thumb($newname,$thumb_name,$WIDTH,$HEIGHT);
                  }           }       }   }       if($action=="Delete")   {       $SelectImage = $obj->sql_query("select $imagename from  $tablename where $fieldname
      
      = ".$$ 字段名。" "); $ThisImage = $SelectImage[0]["$imagename"]; unlink("$uploadpath/thumb/".$ThisImage); unlink("$uploadpath/large/".$ThisImage); } ?>
      1. 列表项

    【讨论】:

    • 欢迎来到 Stack Overflow。抱歉,我只是不明白你在这里想说什么。你需要重新格式化你的代码(我试过了;我放弃了),并解释它为什么有用。
    【解决方案3】:

    您需要使用 php move_upload_file 函数,并且我已经对您的 if 语句进行了更改,这里是有效且经过测试的示例:

    <?php
    
    if (isset($_REQUEST["submit"])) {
    
        $allowedExts = array("jpg", "jpeg", "gif", "png");
        $extension = end(explode(".", $_FILES["file"]["name"]));
    
        if ($_FILES["file"]["type"] == "image/gif" || $_FILES["file"]["type"] == "image/jpg" || $_FILES["file"]["type"] == "image/jpeg" || $_FILES["file"]["type"] == "image/png" && $_FILES["file"]["size"] < 2500000 && in_array($extension, $allowedExts)) {
    
          if ($_FILES["file"]["error"] > 0) {
    
            echo "Error: " . $_FILES["file"]["error"] . "<br />";
    
          }
          else {
    
            $fname = $_FILES["file"]["name"];
            move_uploaded_file($_FILES["file"]["tmp_name"], $fname);
    
            echo "Upload: " . $_FILES["file"]["name"] . "<br />";
            echo "Type: " . $_FILES["file"]["type"] . "<br />";
            echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
            echo "Stored in: " . $fname;
    
          }
    
        }
        else {
    
          echo "Invalid file type";
    
        }
    
    }
    ?>
    <form action="" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" name="submit" value="submit" />
    </form>
    

    您还可以按照建议使用 getimagesize 函数,方法是:

    $size = getimagesize("http://www.simplestudio.rs/060620121945.jpg");
    
    $file_format = $size['mime'];
    

    $file_format 将表示为例如“image/jpeg”,因此您可以轻松检查图像类型,如下所示:

    foreach($allowedExts as $allowed) {
    
    $chk_types = strpos($file_format, $allowed);
    
    if($chk_types > -1) {
    $type_is_good = true;
    break;
    }
    
    }
    

    【讨论】:

    • 是的,它添加了图像,并显示了有关它的信息,但是安全吗?我尝试上传 .crx 文件但失败了,但有什么办法可以解决吗?
    • 我已经编辑了我的答案以添加使用 getimagesize,因为它比 $_FILES["file"]["type"] 更安全。除此之外,您可以检查用户代理作为对机器人的基本检查(即使这可能被机器人伪造)。但请随时在 Google 上获取有关图片上传安全性的更多信息...
    【解决方案4】:

    使用:move_uploaded_file,见,Manual

    还有一件事,

    $_FILES["file"]["type"] 变量不好使用,因为它可以通过浏览器设置进行更改。

    请改用 getimagesize,请参阅,Manual

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-18
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-09
      相关资源
      最近更新 更多