I recently helped a friend evaluate a web she had developed for her. The business is essentially a web based business, but she is not a web developer herself so had the development outsourced to a reputable local web design company. At first she was happy with the result them some things were going a miss and one of her business partners who fancied themselves as a hobbyist nerd found a security hole. This raised some concerns and then she approached them and they had it fixed up. When Alice* told me about this I was rather uncomfortable with the whole scenario. How is a hobbyist able to identify security holes in a web site?!
Alice sensed my concern (probably due to the swearing and head in hands), and asked if I was able to have a quick review of the site. The good news was they fixed up the SQL Injection vulnerability. Bad news was, that was about it. Now I am a professional developer working exclusively in the .NET space. I am aware of certain security issues and would place myself as a somewhat knowledgeable in areas of security, but by no means a Bruce Schneier or Keith Brown. It took me 4 hours with the use of notepad, skydrive and a browser (ie free and available software) to have cross-site scripting attacks up and running. I was able to fetch my own password from the cross site script and also hijack my session. Having done this I flicked Alice an email and let her know the bad news.
This made me think, are the web developers out there writing secure applications yet? In fact is anyone? The last place I worked, they commissioned a guy to write his own custom federated security model for an internal system. Yeah the words Federated and Internal seem to conflict eh. Well that system took only 90mins to hack open. Irony is that Windows Authentication would have been more secure and faster. The place I am currently working they have a recommendation to store username and password pairs in *.config files when trying to authenticate across multiple servers (Kerberos hop anyone?). This obviously is worrying.
So I thought I would throw together a refresher list of things you need to do to make your system, well not insecure.
- Don't store passwords. That's right you don't need them. Ideally you should be using an authentication system (OpenAuth, AD/LDAP etc.) but if you need to roll your own you only need a salted hash of the password to perform a comparison for authentication. Storing passwords is just asking for trouble. If you consider all of the systems the users have to log in to there is a very high chance that either their password is the same everywhere or they have a pattern for picking passwords. If I can hack your Database of passwords then not only can I hack you site, but there is a good chance that I can now hack these user's accounts in gmail, facebook, linkedin etc and even worse...bank accounts or work accounts.
- Sanitise your inputs, and even better don't ever "evaluate" user input as code this comic is a great parody of this. An easy target of this is SQL Injection attacks. SQL Injection attacks just make me shudder.
- As above, only use parameterised SQL. This doesn't favour SPs or dynamic SQL. I have seen vulnerable code in both, but neither needs to be vulnerable.
- In web development, never display foreign or user input to the screen with out encoding it. This is how session hijacking occurs. (basically repeating myself on evaluating user input)
- Use HTTPS for login screens or any screen that passes private/protected data.
- .Net developers should strong name critical assemblies. If you don't, some one can basically use reflector to recreate your assembly and replace your implementation with theirs. I have used this to replace the assembly that performed the login. My implementation was identical except that I logged passwords to a location that I could read later. Interestingly the compiled assembly was identical in size even though I had added code. Changing the file created/modified date to the original wasn't a hassle so no one would be any wiser.
Rocky H used to have a brilliant video on "Assembly Hijacking" which showcased a combination styles of attacks to basically take over a server. The link I have (and the ones Google finds) are dead links. I have emailed him to see if we can get it back on line. Required viewing.
I hope the information here helps someone. If you dont know what any of the jargon above means in detail then there is a great chance that you are writing insecure code. Just Google/Wiki the phrase you don't know, it will take you 10minutes to learn what it is and how to prevent it. Otherwise feel free to ask.
*Alice is not her real name