views:

242

answers:

4

I was wondering what security issues appear when the end user of a website can upload files to the server.

For instance if my website allows the users to upload a profile picture, and one user uploads something harmful instead, what could happen? What kind of security should I set up to prevent attacks like this? I'm talking here about images, but what about the case where a user can upload anything into a file-vault kind of application?

It's more a general question than a question about a specific situation, so what are the best practices in that situation? What do you usually do?

I suppose: type validation on upload, different permissions for uploaded files... what else?

EDIT: To clear up the context, I am thinking about a web application where a user can upload any kind of file and then display it in the browser. The file would be stored on the server. The users are whoever uses the website, so there is no trust involved.

I am looking for general answers that could apply for different languages/framework and production environments.

+4  A: 

Your first line of defense will be to limit the size of uploaded files, and kill any transfer that is larger than that amount.

File extension validation is probably a good second line of defense. Type validation can be done later... as long as you aren't relying on the (user-supplied) mime-type for said validation.

Why file extension validation? Because that's what most web servers use to identify which files are executable. If your executables aren't locked down to a specific directory (and most likely, they aren't), files with certain extensions will execute anywhere under the site's document root.

File extension checking is best done with a whitelist of the file types you want to accept.

Once you validate the file extension, you can then check to verify that said file is the type its extension claims, either by checking for magic bytes or using the unix file command.

I'm sure there are other concerns that I missed, but hopefully this helps.

R. Bemrose
I tried to keep this language agnostic, but for PHP, there's a section of the manual dealing with #1: http://us3.php.net/manual/en/features.file-upload.common-pitfalls.php
R. Bemrose
But what to do if I allow users to upload files that could potentially be harmfull, like .exe files or .sh scripts? Is that something I should just forbid?
marcgg
Yes... either that or just have a whitelist of extensions you'll accept.
R. Bemrose
+2  A: 

Assuming you're dealing with only images, one thing you can do is use an image library to generate thumbnails/consistent image sizes, and throw the original away when you're done. Then you effectively have a single point of vulnerability: your image library. Assuming you keep it up-to-date, you should be fine.

Users won't be able to upload zip files or really any non-image file, because the image library will barf if it tries to resize non-image data, and you can just catch the exception. You'll probably want to do a preliminary check on the filename extension though. No point sending a file through the image library if the filename is "foo.zip".

As for permissions, well... don't set the execute bit. But realistically, permissions won't help protect you much against malicious user input.

If your programming environment allows it, you're going to want to run some of these checks while the upload is in progress. A malicious HTTP client can potentially send a file with an infinite size. IE, it just never stops transmitting random bytes, resulting in a denial of service attack. Or maybe they just upload a gig of video as their profile picture. Most image file formats have a header at the beginning as well. If a client begins to send a file that doesn't match any known image header, you can abort the transfer. But that's starting to move into the realm of overkill. Unless you're Facebook, that kind of thing is probably unnecessary.

Edit

If you allow users to upload scripts and executables, you should make sure that anything uploaded via that form is never served back as anything other than application/octet-stream. Don't try to mix the Content-Type when you're dealing with potentially dangerous uploads. If you're going to tell users they have to worry about their own security (that's effectively what you do when you accept scripts or executables), then everything should be served as application/octet-stream so that the browser doesn't attempt to render it. You should also probably set the Content-Disposition header. It's probably also wise to involve a virus scanner in the pipeline if you want to deal with executables. ClamAV is scriptable and open source, for example.

Bob Aman
I forgot where, but I saw a guide on how to hook ClamAV into Apache as a filter before... at least I think it was into Apache.
R. Bemrose
A: 

With more context, it would be easier to know where the vulberabilities may lie.

If the data could be stored in a database (sounds like it won't be), then you should guard against SQL Injection attacks.

If the data could be displayed in a browser (sounds like it would be), then you may need to guard against HTML/CSS Injection attacks.

If you're using scripting languages (e.g., PHP) on the server, then you may need to guard against injection attacks against those specific languages. With compiled server code (or a poor scripting implementation), there's the chance of buffer overrun attacks.

Don't overlook user data security, too: Can your users trust you to prevent their data from being compromised?

EDIT: If you really want to cover all bases, consider the risks of JPEG and WMF security holes. These could be exploited if a malicious user can upload the files from one system, and then views the files -- or persuades another user to view the files -- from another system.

Dan Breslau
HTML/CSS injection don't really apply to uploaded files, which is what the question is about.
Bob Aman
Sporkmonger: As I wrote, it depends on the context. Based on the way the question is worded, there are definitely systems that could fit that description that could have these vulnerabilities.
Dan Breslau
Fair enough. It would be possible to upload HTML, and if he's not careful, yeah, he might accidentally serve it up as a page.
Bob Aman
I wasn't really talking about XSS attacks or things like that, but this is still something to keep in mind. JPEG and WMF security issues was interesting to read :\
marcgg
+1  A: 

size validation would be useful too, wouldn't want someone to intentionally upload a 100gb fake image just out of spite now would you :)

Also, you may want to consider something to prevent people from using your bandwidth just for a easy way to host images (I would mostly be concerned with hosting of illegal stuff). Most people would use imageshack for temp image hosting anyway.

yx