1

I currently am building a file uploader for a site im building and i have a problem with file types, I need it to be able to upload html, css, javascript, json files, but not PHP etc. My problem is i cant seem to figure out the file type names. See below for more detail.

<?php
 if (($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
{
if ($_FILES["file"]["error"] > 0)
  {
  echo "Return Code: " . $_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 "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

  if (file_exists("upload/" . $_FILES["file"]["name"]))
  {
  echo $_FILES["file"]["name"] . " already exists. ";
  }
else
  {
  move_uploaded_file($_FILES["file"]["tmp_name"],
  "upload/" . $_FILES["file"]["name"]);
  echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
  }
   }
  }
  else
  {
  echo "Invalid file";
  }
?>

Where it has image/jpeg, i have tried .html and html to no avail, as well as .js etc and i just cannot figure it out! HELP!!! :D

3
  • try adding more comparison against $_FILES['file']['type'] at IF, for example text/html Commented Jun 26, 2012 at 9:22
  • Note that filetype / mimetype can be spoofed, it's not reliable Commented Jun 26, 2012 at 9:26
  • @jayhassett89: Why do you want to prevent PHP files? Is it because of security? Because if it is so, uploading HTML (or in that case even JPGs/etc for some browsers) can get you an XSS attack. Commented Jun 26, 2012 at 9:41

3 Answers 3

3

If you are referring to:

echo "Type: " . $_FILES["file"]["type"] . "<br />";

This is the mime type. If you want to look at the file extension, you have to parse the filename itself. E.G:

$ext = substr(strrchr($_FILES["file"]["name"], '.'), 1);

To allow/disallow, it's a good idea to use switch:

switch ($_FILES["file"]["type"]) {
    case 'image/jpeg':
    case 'image/gif':
        // Allowed
    break;
    default:
        // Not allowed
    break;
}


switch ($ext) {
    case 'jpeg':
    case 'gif':
    case 'jpg':
        // Allowed
    break;
    default:
        // Not allowed
    break;
}
Sign up to request clarification or add additional context in comments.

2 Comments

$_FILES["file"]["type"] can be spoofed!
thank you, the file extension was probably a better idea anyways security wise, sorry if my question was unclear :)
0

Might I suggest a different approach?

Instead of relying on file type, examine the extension.

Little example of this would be:

$parts = array();
$parts = explode( ".", $_FILES['file']['name'] );

if ( !empty($parts) && is_array($parts) ) {
    $extension = end( $parts );
} else {
    echo "File name has no extension";
}

if ( $extension == "jpg" || $extension == "jpeg" ) {
    // Do something with the jpeg
} elseif ( $extension == "html" ) {
    // Do something with html
} elseif ( $extension == "js" ) {
    // Do something with js
} else if ( ... /* You can add any conditional based on extension here */ ) {
    // And do whatever you want here
}

This is a vary basic, crude example with multiple if / elseif statements, you can make a switch condition, make a factory class, etc... But the idea stays the same.

Cheers.

2 Comments

Having if trees like this is generally not good practise. You should use switch/case instead.
Agreed, I noted this is just a "top of the head example" and that it should be done differently under the code sample. :)
0

It's not safe to rely on the client file type in $_FILES, you'd better get it from the file content.

function mime_type($file_path)
{
    if (function_exists('finfo_open')) {            
        $finfo = new finfo(FILEINFO_MIME_TYPE, null);
        $mime_type = $finfo->file($file_path);
    }
    if (!$mime_type && function_exists('passthru') && function_exists('escapeshellarg')) {
        ob_start();
        passthru(sprintf('file -b --mime %s 2>/dev/null', escapeshellarg($file_path)), $return);
        if ($return > 0) {
            ob_end_clean();
            $mime_type = null;
        }
        $type = trim(ob_get_clean());
        if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-\.]+)#i', $type, $match)) {
            $mime_type = null;
        }
        $mime_type = $match[1];
    }
    return $mime_type;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.