1

So I have a client wants a photography site where users can upload their photos in response to photography competitions. Though technically this isn't a problem, I want to know the risks associated with allowing any user to be able to upload any image onto my server. I've got the feeling the risks are high...

I was thinking of using something like this http://www.w3schools.com/php/php_file_upload.asp

If I do let anonymous users upload files, how can I secure the directory the images (and potentially damaging files) will be uploaded into?

Starkers
  • 10,273
  • 21
  • 95
  • 158
  • 3
    do not EVER use anything from [w3fools](http://w3fools.com). Their code is crap and highly insecure. They're not a useful resource in any way/shape/form. They're basically just a spam site that's got good SEO. – Marc B Mar 19 '13 at 11:55
  • @MarcB Noted. However, what I'd write would something SIMILAR to that script in regards to complexity. It wouldn't be a copypasta job. – Starkers Mar 19 '13 at 11:58
  • http://stackoverflow.com/questions/15433563/something-wrong-with-the-quotations/15434585#15434585 – DaveRandom Mar 19 '13 at 12:09

3 Answers3

1

if you want to be sure that the image is a real image you can load using gd http://www.php.net/gd

if the gd resource is created correctly then the image is a real image

first detect the mime using:

getimagesize($filename);

then, for example if it is a jpeg load into gd:

$gdresource = imagecreatefromjpeg($filename);

if $gdresource is valid/created without warnings, the image is valid and not corrupted... getimagesize() is (probably) not good enough to detect corrupted images

also, another important note... don't rely on $_FILES['blabla']['name'] because it could contain non valid utf-8 sequences (assuming that you are using utf-8 for example) and it could be a potential attack mechanism, as any user input

so you'll need to validate / sanitize that as well

$originalFileName = $_FILES['blabla']['name'];
$safeOriginalFileName = iconv('UTF-8', 'UTF-8//IGNORE', $originalFileName);
// more additional checks here. for example filename is empty ""
move_uploaded_file(...., $safeOriginalFileName);

also, remember that $_FILES['blabla']['name'] contains the file extension, which may not be correct. so you'll need to strip it out and use the actual correct extension (that you previously resolved using getimagesize() + imagecreatefrom*())

 $safeOriginalFileName = basename( $safeOriginalFileName ); // removes the extension
 $safeOriginalFileName = $safeOriginalFileName . ".jpg"; // correct extension

hope this helps :)


also as DaveRandom pointed out, don't rely also on $_FILES['blabla']['type'], use instead as I suggested getimagesize() + imagecreatefrom*()

0

The uploaded file is stored at a temporary location, this location can be found in the $_FILES variable.

When your script accepts the uploaded file, you can use move_uploaded_file() to move it to the location of your choice.

So even the user is anonymous you are in control what to do with uploads and whether to accept them (eg based on content, size, etc.) or not.

Furthermore, the (anonymous) user provides the file and accompanied details. So, if you blindly use these details, your are vulnerable (a user with bad intents is probably providing the wrong details, to make it legit). So, if you need these details, gather them yourself (instead of using $_FILES)!

For more information see the PHP documentation

Veger
  • 37,240
  • 11
  • 105
  • 116
0

You will have to research a bit, but mainly these are the main hints:

  • The basic security you can have is to check actually the image's MIME type and extension. Although this is certainly easy to forge.

  • Use binary safe functions like readfile(), fopen() and file_get_contents(), I don't remember exactly which ones but there was a few php functions that had security issues handling files, research which ones are and avoid them.

  • There are some functions out there using preg_match() and similar that will check if there's something similar to a script in the file you are reading. Use them to make sure there isn't hidden scripts. This will slowdown the process a bit as preg_match() can be resource expensive reading big files but it shouldn't be very noticeable

  • You could also trigger an antivirus to run on the files uploaded as the email services do.

As far as I know the potentially damaging images would normally contain scripting languages, like php code or javascript to try XSS attacks, there are a lot of dangers out there, so I guess you can't guarantee 100% de safety of the files, but keep having a look periodically to see all the new dangers and ways to avoid them.

aleation
  • 4,796
  • 1
  • 21
  • 35