IVTEC Web solutions, made to fit

Image uploads without surprises

The extension means nothing, and the MIME type the browser sends means even less. What is left is re-encoding.

Illustration for Image uploads without surprises

The upload form is the most common way into a PHP site. Not because PHP is fragile, but because it is easy to trust what the browser sends.

What is not a check

  • The extension in the file name. The attacker picks it.
  • $_FILES['x']['type']. The browser sends it, so the attacker sends it.

What is

$info = @getimagesize($tmp);
if ($info === false) {
    throw new RuntimeException('That file is not an image.');
}

And, more importantly, re-encoding through GD. A file with PHP code hidden in an EXIF comment does not survive a round trip through imagecreatefromjpeg and imagejpeg.

The last safety net

Even if everything above failed, the upload folder must never execute anything:

<IfModule mod_php.c>
    php_flag engine off
</IfModule>
RemoveHandler .php .phtml .php5

The IfModule matters: on hosting where PHP runs as FastCGI, a bare php_flag returns a 500 for the whole site.

Related posts