title: Prevent image upload code injection
body: <p>I have a form which the user fills with lyrics information and uploads an album cover. Submitted data will be inserted into a database and the album cover will be moved to a subfolder.</p>
  
  <p><code>localhost/project-folder/covers</code></p>
  
  <p>I've taken some precautions (escaping, prepated statements) against SQL Injection for the form input. Recently, I've learned that I also need to take precautions for file (image) upload, that the user can upload malicious images.</p>
  
  <p>For example, adding HTML, JS or PHP code in image metadata, or <a href="http://lcamtuf.coredump.cx/squirrel/" rel="nofollow">embedding code directly into the image file</a>. Since I haven't used PHP extensively, I don't how how this poses a problem, especially in my case.</p>
  
  <p>I'm doing the form validation on the server-side.</p>
  
  <p><em>localhost/project-folder/lyrics/add.php</em></p>
  
  <pre><code>&lt;form action="../scripts/lyrics/submit_lyrics.php" id="lyricsForm" method="post" autocomplete="off" enctype="multipart/form-data"&gt;
  </code></pre>
  
  <p><i>localhost/project-folder/scripts/lyrics/submit_lyrics.php</i></p>
  
  <pre><code>$form_data  = new FormData(["artist", "album", "song", "year", "track_no", "lyrics"], "sssiis");
  $file_data  = new FileUpload("cover", [
      "max_file_size" =&gt; 512 * 1024,
      "extensions"    =&gt; ["gif", "jpg", "jpeg", "png"],
      "mimes"         =&gt; ["image/gif", "image/jpeg", "image/png"],
      "max_width"     =&gt; 1024,
      "max_height"    =&gt; 1024,
  ]);
  $cover = new Cover($mysqli, $form_data, $file_data, BASE."covers/");
  </code></pre>
  
  <p>Validation is done at the initialization of <code>FormData</code> and <code>FileUpload</code>. If there is an invalid field or the uploaded image is invalid, user is redirected back to the form page (add.php) with the corresponding warnings.</p>
  
  <p>One of the ways to prevent malicious image upload that I've read was to create a new image from the uploaded one, and that is what I'm doing inside <code>new Cover()</code>. I also resize the uploaded image so this approachs works. I'm doing the resizing with this function:</p>
  
  <pre><code>public function new_image($file_data, $new_width, $new_height) {
      $img_data   = file_get_contents($file_data-&gt;tmp_name);
      $image_type = $file_data-&gt;type;
      $img_create = null;
      switch ($image_type) {
          case IMAGETYPE_GIF:
              $img_create = "imagecreatefromgif";
              break;
          case IMAGETYPE_JPEG:
              $img_create = "imagecreatefromjpeg";
              break;
          case IMAGETYPE_PNG:
              $img_create = "imagecreatefrompng";
              break;
      }
      $uploaded_image_resource = $img_create($file_data-&gt;tmp_name);
      $new_image_resource      = imagecreatetruecolor($new_width, $new_height);
      imagecopyresampled($new_image_resource, $uploaded_image_resource, 0, 0, 0, 0, $new_width, $new_height, $file_data-&gt;image["width"], $file_data-&gt;image["height"]);
      return $new_image_resource;
  }
  
  public function write_to_disk() {
      if (isset($this-&gt;image["resource"])) {
          $destination = $this-&gt;target_dir . $this-&gt;file_name . ".jpg";
          imagejpeg($this-&gt;image["resource"], $destination);
          imagedestroy($this-&gt;image["resource"]);
      }
  }
  </code></pre>
  
  <p>This resizing also removes (I think) any code in metadata and/or code embedded in the image (if there are any) since I'm creating a new clean image.</p>
  
  <p>Is this enough for file upload protection? Am I missing anything? Are there any other things that I need to be aware of? </p>