Simple steps for security
Wednesday, June 3rd, 2009Security is a complicated monster to tackle, so it helps to think about it in really, really basic terms. Stuff comes in, stuff goes out. We have to assume that anything that comes from the user is dangerous, or tainted, and can’t be trusted in any way what so ever. We don’t even know for sure that the user is who they claim to be. Trust no-one. We also have to be 100% sure that anything we send back to the user is safe, un-tainted, and uncompromising. You don’t want to send dodgy scripts to your users, and neither do you want to send back valuable clues to the inner workings of your code. This is not meant to be an all-encompassing guide to preventing attacks, but instead a set of guidelines to writing applications in secure way.
Minimise
The first rule is this. Minimise areas that accept input from the request, and minimise areas that send response. Sanitisation and validation should be the first thing you perform on data received and the last thing before you return it. Following a sensible architecture such as the Model View Controller approach separates data received by the Controller area and data returned to the View. This will make your life far simpler when you start tackling such issues. This applies to all forms of input (form data, querystrings and cookies) and all forms of output (HTML, redirect, file download).
Validate
A commonly overlooked validation is confirming the data has been intensionally sent from the user. There’s nothing to stop a 3rd party website posting to your website, so it doesn’t matter how secure your login form is, the posted data could be coming from any of the dodgy websites your user has open. An easy solution is to use a random key as part of every posted form, unique to the users session. This way you can easily verify the form has been posted from a tightly controlled page you served to your user. It’s not enough to look at referrer headers, because these are easily faked. ASP.Net web forms, to their credit, do this by default.
Use White-lists over Black-lists. Lets say for example you’re validating a phone number, you don’t specifiy every non-digit character you want to remove, you strip everything that isn’t 0-9. A little too obvious? The same applies to the classic script tag. If you start trying to remove every form of <script> tag, you’ll end up playing catch-up against tricks using <img>, <body> and clever encoding. If allowing any kind of HTML through is necessary, you’d better be damned sure who submitted it and who is going to be able to see it.
Storage
So you’ve received your data, it looks pretty good. Whatcha gonna do with it? If it’s heading towards a database, you can’t be too careful. Escape it, or better yet use parameterised queries. If it’s the file system that your data is ending up, put it somewhere sensible. Ideally, this would be somewhere outside of your webroot, or in a protected folder. Whatever happens, you don’t want anything here directly accessible or executable. Just to be sure.
Responses
OK, so we’re sending a response. Just because the data we received passed our tried-and-tested validations doesn’t mean it’s safe to send back to the user. We HTML encode everything, unless absolutely necessary. If it’s plain text, fairly straight forward. If you’re putting suspect data into an HTML attribute, it might be an idea to verfify the format. If you think you’re outputting an SRC or HREF, check it at least looks like a path. If your response happens to be a redirect, double check nothing funny is going on with the URL. If your response is a (serious) error, make it look friendly, but don’t give away exactly what went wrong. If you want to send them a file, attaching it and manually setting the MIME type is more controlled to simply pointing them at the file.
This is not intended as a set of golden rules, rather a few key points to help you think about the code you write. Most new forms of injection and hackery are just clever ways of attacking poor code. Writing sensible code will keep you one step ahead of such attacks.








