A server administrator I know referred me to this post on file upload security : http://www.uno-code.com/?q=node/93 this morning. An interesting article, rather well written, and pretty informative. It is obviously targeted at people who are hosting sites on their own server though, so I thought I would take a look at how these recommendations stand up to a shared hosting environment and comment on them from the point of view of a software developer. My tone may wax a bit sarcastic from time to time – this is nothing to do with the author of the original article. I’d like to give some credit to the author, but they really don’t have any ID on their site. No info on the website, no info on the website referred to in the whois information. So, thanks go out to “The Artist Known as Admin AT uno-code.com” , (aka “The Artist”). Whoever they are.
The article centers around 10 things that can be done to achieve file upload security on your Apache based server. Those ten things are:
- Don’t allow uploads
- Check MIME type server-side
- Use mod_security to validate file uploads via a approver script
- Use suhosin. Suhosin (was/is ?) the hardened-php project
- Don’t upload to a web accessible directory
- Pay attention to permissions.
- Don’t serve certain file types if you need to have a web accessible upload directory.
- Make sure your /tmp directory is not executable
- Chroot your Apache environment
- Use safe_mode and open_basedir
You would think this is a fairly useful list, and perhaps it is. The author addressed each of these issues with a paragraph or so of comments. I’ll summarize those below, and offer discussion..
Don’t Allow Uploads
The Artist apologizes for restating the obvious, and notes that if you disallow file uploads on the entire server, you don’t have to worry about them. Good advice as far as it goes, just not always practical on an eCommerce Server. In any case, the conditions under which a server or server account are rented often do not allow the system administrator a choice here. More on this later.
Check MIME type server-side
Excellent advice. The Artist follows with some practical tips on how to do so, part of what makes the article well worth reading. It is well worth repeating that the mime-types passed during content negotiation may be spoofed and that these should be checked server-side before accepting the file into permanent file storage. The techniques using PEAR’s fileinfo package and GD’s exif_imagetype() should certainly be helpful – provided they are available.
Use mod_security to validate file uploads via a approver script
OK – not a bad idea. But – how? Not so much from a technical standpoint, as from a protocol perspective. File uploads are generally enabled because the site owner needs that feature, and needs certain file types. Should the System Administrator blindly stop an upload without communicating the issue to the site owner?? I don’t think so. The fact is, file validation on uploads is a shared responsibility. Either the system administrator or the application programmer should be providing a service which can be used to assure that validation is done. This is a significant need in shared server space, because simply blocking the upload steps on the tenants rights to access their property – ie, their rented server space. Subjecting all uploads to scanning is a good idea, but this also should not be done without interaction with the site owner. Emailing them on discovery of malicious content upload would be good – and if you can use mod_security or other techniques to tie the content to its source so much the better. In short – don’t do so blindly and capriciously without regard to the site owners need to be aware of events taking place on their site.
Use suhosin. Suhosin (was/is ?) the hardened-php project. Well, maybe. My own experience running PHP software on Suhosin is that it may be hardened, but it requires due diligence in site setup and/or application development for a reasonable level of confidence in application performance to be reached. My experience with PHP development in general tells me that it would be a very good idea not to urn any business software on Suhosin that wasn’t developed on it. (Which by the way – I highly recommend.). So – I don’t disagree with the recommendation, but I think as a flat policy statement it may be better offered to PHP developers than the general public. It leaves the question – why is Suhosin not a standard part of PHP ?
Don’t upload to a web accessible directory. Oh please. Good idea on some servers, and totally irrelevant on others. Depending on the server setup, this just could allow any malicious program escaping validation and scanning free entry into other parts of the server. Do this if and only if your server administrator specifically advises you to, and provides a specific location to which the uploads may be routed. Administrators should make this part of their server setup routine, and include the information in welcome emails.
Pay attention to permissions definitely a good idea – and for system administrators I would add pay attention to ownership as well. Part of the reason for my position on the last suggestion offered.
Don’t serve certain file types if you need to have a web accessible upload directory. Good advice. What file types? Many merchants have little to no clue. This is a place where closer collaboration between hosts and hosts and their clients could really pay off for security – especially when combined with some creative account configuration and construction techniques. For hosts to collect intended usage information and issue focused security advisories could be very helpful to all concerned.
Make sure your /tmp directory is not executable. Not bad advice at all. Here is another for use in a shared hosting ecommerce environment – make sure your users can create their own space in the /tmp directory separate from any other users space, provide such separate space up front or advise the use of database stored sessions. Why? Session identifiers are generally pseudo random in nature – but the key portion of that description is “Pseudo”. The total number of times I have seen an exchange of confidential customer information occur because of shared /tmp directory space is quite small in terms of the total number of annual transactions which occured on the servers obverved – but are in double digits, which was quite enough for the people involved. If a host wants to lease server space to ecommerce sites, they should be aware of this and offer guidance to the best solution for their server configuration up front.
Chroot your Apache environment – great advice anytime, I think.
Use safe_mode and open_basedir – way off_base. Sorry Artist – but safe_mode is going away in PHP 6, or hadn’t you heard? Every server administrator should be aware of this change – nor is it a bad thing. It may be a mode, but it is not safe nor does it assure code safety any more than turning Register Globals off. During the time safe_mode was available it diverted attention from other secure programming techniques by interfering substantially with access to normal programming techniques. No security tool provided by a mere application development language can substitute for a secure implementation of basic services including email, shell, FTP and web servers and the close attention to file ownership, and permissions advised above. Offer tutorials in the secure use of the services you make available as part of your business. Orient your customers as to security policy, then enforce it. Most of them will thank you, and those that won’t need to be elsewhere.