I use the PHP language for file upload and want to know that the following method that I use is secure or not?
I am using simple method for file uploading,
I check the file name from $_FILES[‘userfile’][‘type’]
and then if it’s having an allowed file extension, I upload the file with some random number.
Like if it is abc.zip it may become 8w43x9d.zip.
Please tell me: is it a really bad method for file upload?
Randomly-generated safe filenames are definitely a good thing. However if you allowing the file extension through to the webroot you’ll still need to ensure that the extension is something that won’t cause any problems on the server, such as
.php(OK, PHP handling should be disabled in the web server for upload directories, but still). There are also problems if you are on a Windows server, where trailing dots and spaces will confuse the filesystem; make sure you lock down the extension to a few ‘known good’ values.Unfortunately the
['type']property cannot be relied on at all. Some browsers won’t fill a content-type in, others will put the wrong type because their OSes are set up badly (an infamously unhelpful one is that IE on Windows by default calls JPEGimage/pjpeg), some will always sayapplication/octet-streamor eventext/plain.Even the
['name']property is unreliable; apart from browsers lying or obfuscating the value, there’s always the chance a given type will have an unexpected file extension on that particular machine. Or, for Mac and Linux clients, it’s entirely possible an uploaded file won’t have an extension at all (or may even have the wrong extension for the type the OS sees it as).So yeah, this is all a bit of a mess. Whilst sniffing for type from the Content-Type submission or filename extension can be useful to guess what default type a file should be, it’s entirely unreliable, so it’s a good thing to provide a manual method to choose the type of a file in addition. Alternatively, if you are serving the uploaded files as attachments (eg. through a PHP script setting
Content-Disposition: attachment), you can often get away with just calling everythingapplication/octet-streamand letting the user sort it out when they save it.If you’re not serving as an attachment, you may have a security problem. IE will happily sniff many filetypes you serve it for
<html>tags and treat those files as HTML even if you tell it they’re something else. Then it can display them inline in the browser, and lets them inject script into your security context. If you have anything significant in your security context, such as user accounts and cookies, that’s a cross-site-scripting security hole. The workarounds for this are serving as attachment and/or serving from a different hostname that is not in your main site’s security context (typically, a subdomain is used).Allowing users you don’t completely trust to upload files to your server turns out to actually be a much more difficult task than the trivial example code in PHP tutorials would lead you to believe. 🙁