Friday, March 30, 2012

Advice on Input Validation

Wrote this today for school and I thought it was good enough advice to put it out there for the everyone. Same disclaimer as all my school posts applies, as well as that this is an opinion piece. Enjoy.

First, everyone will beat validation into your head. Stop. Take a step back, and realize that for most applications ease of use is more important. When you design you should not ignore good design patterns, but you should focus on what will make the program work and what will work for the user. If you are too worried about security from the onset then you are likely to make programs that "suck", not because they're not useful or they're poorly written, but because the primary concern was avoiding malicious users rather than designing great software.

Second - and this will seem counterintuitive - is that security also shouldn't be an afterthought. It should come second, and eventually it should come naturally with good design patterns, but every program you write should have some programming time budgeted to make sure it is as secure as need be. If it'll take you a week to make it right, then be sure to budget an extra day to button it down.

Third, it should be part of every layer of the program. Even if you're not doing a strict MVC pattern  it's best to note that most web apps have those layers anyway, they're just jumbled up a bit. Sure, your forms need to be checked for bad input, but if you have data objects behind them you should probably check there too, at least to some extent. (This is where having a strongly typed language helps, you can control what data hits your mid-tier in a very natural way.) This one is especially important if you ever work as part of a group. Do not trust your fellow programmers to validate. Even if they are competent, they may believe that you're doing the validation and skip it themselves.

Fourth is an extension to the third, but it's so important it needs its own paragraph. Always check things going to your database. Sure allowing the wrong form input can enable an XSS attack, but your database is almost always your lifeblood. Guard it appropriately. A design pattern you should pick up in this area is that whenever it is available you should not quote a variable into a SQL statement, that is how SQL injection vulnerabilities are born. The article you linked to missed this. If you're using PHP 5 you should use the PHP Data Objects library and use bindParam to add the parameter value.

Fifth is that input validation is not the only way you will be protecting yourself. One of the biggest problems you'll find in the real world is test code left active in deployment. For example:

I had to check a bug in a classic ASP script a few months back. It was the login page for an external application. To my horror I found that after the standard input validation done on the username, the password was passed in untouched by concatenation to a SQL query. Worse, this entire query was written back to the login page in an HTML comment. It'd been years since this was touched, and the keys were under the mat the whole time.

Probably the best way to guard against security holes is to develop and stick to best practices. Using SQL parameters is a best practice. Get yourself into the habit of doing this. When you develop these practices they'll soon become second nature, and that will allow you to go back to step one and focus on the design first. It'll also make step two easier but still necessary.