How not to be an incompetent developer
Sunday, November 27th, 2005The last few entries I’ve called developers incompetent for their security flaws, in the comments, some people have thought this unfair of me. They rightly point out that security is not easy, so it wasn’t reasonable to call people who fail incompetent, I stand by my description though. Security is hard, but this type of security problem certainly isn’t, in fact it’s not just a security problem, it’s also a “the site doesn’t work” problem.
The fundamental cause of these problems is content being written into the page unencoded, so the character < is considered the start of an HTML element, rather than part of the content. Or if the content is being written into an attribute then the character " or ' are considered to be the end of the attribute. (or even a simple space if you don’t bother quoting your attributes) This lack of encoding isn’t just a security flaw though, the site simply won’t work properly, as any test data that includes the characters won’t appear correctly on the page, this is the main reason why I blame incompetence on the testers and developers, or simple laziness, and not bothering to test at all.
Steps a developer can take
Hare are 3 simple things I use as a developer to mitigate the risk.
- Have < " in your toy test data, easy of course in your text input boxes, but also do it in your select values and radio values, that way you never need to actually test by directly entering a risky querystring, you can leave that to the tester, yet you’ll still catch the bug as you’re developing.
- Place all non-html output variables into a single object, it doesn’t matter if the input comes from the user, or the database, it still needs to be encoded, okay a number should never need encoding, but there’s little lost to doing so anyway and you’ll reduce the risk from untrusted data. You can make this object only output encoded content, e.g. in javascript, you could use something like:
function safeString(str) { this.value=str; } safeString.prototype.toString=function() { return htmlencode(this.value); } safe=new safeString(\"<script>alert(1)</script>\");document.write(safe);Of course you can still make the mistake and not use your object, but it should be much easier to spot the bug early in the process.
- This is mainly the testers job of course, but in an idle moment you should change the query string of any page to include a load of the bad characters, and just see if the page is happy, they should appear just like any other character does.
These methods won’t stop all security problems, you’ll still need to think properly about security, but they at least make you a step above the current Google or Yahoo developer.