Jump to content

Validating file uploads


NotionCommotion

Recommended Posts

I have the following amazing script.  I see that the file type is "application/vnd.ms-excel".  I will later use FILEINFO_MIME_TYPE to make extra sure.

 

My question is whether I should even look at $_FILES['myFile']['type']. It come from the client, right?  furthermore, I've seen some browsers provide different types.  Maybe best to go just off extention and mime?

<?php
echo('<pre>'.print_r($_FILES,1).'</pre>');
?>

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Testing</title>  
    </head>

    <body>
        <form method="post" enctype="multipart/form-data">
            <input type="file" name="myFile">
            <input type="submit" value="Upload">
        </form>
    </body>
</html>
Array(    [myFile] => Array        (            [name] => contacts.csv            [type] => application/vnd.ms-excel            [tmp_name] => /tmp/php6c1Knk            [error] => 0            [size] => 137271        ))
Link to comment
Share on other sites

To me it can eliminate something earlier not allowed before having to call the pecl extension.

 

I'd say check both.

 

Both being $_FILES['...']['type'] and mime, or file extention and mime?

 

On a related side note, do you know of a maintained class that quickly takes into account $_FILES['...']['type'], extention, and $_SERVER['HTTP_USER_AGENT'] to pre-screen files?

Link to comment
Share on other sites

What exactly are you trying to achieve, NotionCommotion?

 

If the MIME info in my request says “§%&!” or “application/dangerous-php-script”, will you reject it? Why? Isn't this info entirely irrelevant?

 

Also, what are you trying to achieve with server-side MIME sniffing? This merely checks the basic structure of the file or the presence of some magic bytes. It does not say anything about the actual file content. For example, it's perfectly possible to embed malicious code into a PNG structure.

Edited by Jacques1
Link to comment
Share on other sites

What exactly are you trying to achieve, NotionCommotion?

 

I wish to make it difficult to upload files except for given types such as Word/Excel/PDF or whatever.

 

Yes, I will reject it if MIME doesn't match either $_FILES['...']['type'] or the extention or both.

 

The purpose it to provide reasonable protection to other users which might download the files.

 

Users will download the files directly from the web server (or maybe XSendFile if I am using Apache) and it will need to be configured to not parse PHP so I don't think I have “application/dangerous-php-script” risk.

Link to comment
Share on other sites

Like I said, neither the MIME info nor the extension nor the result of finfo_file() say anything about the actual file content. A harmless file doesn't become malicious just because the browser has somehow gotten the MIME info wrong, and a malicious file doesn't become harmless just because it's declared as a PDF document or starts with a PDF header.

 

So none of those methods provide protection. At best, they can help well-meaning users detect errors (e. g. they accidentally uploaded the wrong file).

 

Protection depends on how you deliver the file:

  • Serve it as an attachment or make sure the Content-Type is harmless.
  • Make sure the target file extension (which doesn't have to be the original extension) is harmless.
  • Serve the file from a separate domain.
  • Consider doing a malware scan (how much this helps is debatable, of course).
Link to comment
Share on other sites

Why?

 

Because if a cross-site scripting attack happens, the same-origin policy will prevent the code from accessing your actual site.

 

 

 

So don't even do them?

 

Or do them, and know they are not comprehensive and will only deter amateurs?

 

I wouldn't do any checks for the sake of (pseudo-)security, no.

 

But of course you need to somehow determine the intended file type. Personally, I use the file extension. Since Windows is very picky about the extension, that's usually a good estimate. If no file extension is present, you may use the MIME info as a fallback. Whether you take the client-provided info or do your own check doesn't make much of a difference, but since the server-side check is guarenteed to return a valid type, it may be preferrable.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.