5

In my uploading user's avatar scenario, I change users picture extension to jpg. Is this making the browsers to act differently? Is it prone to error for browsers when they read users avatar? Moreover, does it make my web app more secure when an attacker upload a php file?

3 Answers 3

5

When you are uploading files you should insure that the file extension is one that you approve, other wise known as a white list approach. You shouldn't rename every extension to .jpeg, this will cause problems. Most HTTPD's will set the mime type based on the file extension, which informs the browser of how to decode the content.

There is another problem with file uploads. Apache will "fall back" on the 2nd file extension if it doesn't have a mime type for the first file extension. So by default, backdoor.php.fjfl will execute as a .php file, Ouch. I recommend renaming the file, like to the primary key, on top of having a white-list of file extensions.

Even if the user is uploading a valid image it can still cause problems for security. For instance, the images metadata could contain a php tag, which is useful in turning a simple Local File Include vulnerability into remote code execution.

1
  • backdoor.php.fjfl really freaked me out!! tnx @Rook
    – Alireza
    Dec 26, 2011 at 4:38
8

As @Rook said you shouldn't change the extension as it will cause problems. He also pointed out that the metadata could contain malicious data, which is very true. So here are the steps you should follow, roughly:

  1. Check file size - Is it massive enough to break the web server through DoS?
  2. Check extension - Is it a known extension that you support, e.g. jpg, png, gif
  3. If extension is good, check file header - Even though it says jpg, it could contain GIF/PNG/EXE header, etc
  4. Strip metadata from file - Don't even read it, just delete it
  5. Convert to format of your choice if you want it in a given format

In the event that any of the above checks fail you just stop the process and delete the file and return a simple error message explaining that the image is no good.

4

(1) Never use any part of a user-submitted filename in your stored filename. Sanitising a filename is a treacherous job, not as easy to do reliably as it looks at all—especially if your app might end up running on a Windows as well as Linux server.

Store it as something like 2395862.jpeg, with the filename derived from eg the primary key of the related database entity.

If you need to present a ‘friendly’ name to the end browser, use a rewrite so that you can serve it as /avatar/2395862/anyname.jpeg whilst it's actually stored as 2395862.jpeg.

(2) Ensure you store the files in a separate directory that contains nothing else. This directory should be the only one the web script user has write access to. It should have locked-down permissions so only static files can be served from it. On Apache this should be done from a higher-level .htaccess or httpd.conf and overrides turned off so that it's not possible for writing a .htaccess file in this directory to have any effect.

(3) It's possible for user-uploaded files to contain content that masquerades as a different type. For example in some browsers the presence of HTML tags in the file may cause them to treat the file as an HTML document, including JavaScript. Plug-ins can also misinterpret files resulting in cross-site scripting (see the GIFAR attack for an example).

For this reason, you should consider any user-uploaded-file repository to be compromised for cross-site-scripting, and mitigate this by serving all your user-uploaded files from a different domain. That way any injected script won't be able to cross-site-script into your main web site. Ensure that there is no way to access to user-uploaded resources from your main web site.

The separate site for user resources can be a completely different domain, or it can be a subdomain. But if it's a subdomain you must ensure that there is nothing on the parent domain: so if you serve user resources from avatars.myforum.com your main forum can be at www.myforum.com but it must not be at myforum.com. Otherwise browsers will share cookies between them.

2
  • Actually the "friendly name" part is interesting, could you reference me to a tutorial or some like that. tnx @bobince
    – Alireza
    Dec 26, 2011 at 12:46
  • How rewrites are done depends on your web server. For Apache see mod_rewrite, the directive would look something like RewriteRule ^avatar/(\d+)/[^/]+\.jpeg$ data/$1.jpeg. (reposted, expression was missing parentheses)
    – bobince
    Dec 26, 2011 at 15:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .