I write a lot about website security. Sometimes I’ll publicly point out flaws in software but there are many, many other times where it remains a private conversation for various reasons. The one common thread across most of these incidents is that as developers, we often make bad security design decisions. It’s us – the organic matter in the software development process – that despite the best of intentions make bad choices that introduce serious risks.
My belief – and one of the key reasons I so frequently write publicly about security – is that the best way to combat risks in software is to educate developers. All the security scans and penetration tests in the world won’t help when it can take just a single line of bad code or a solitary configuration setting made by the developer to bring everything undone. Of course it’s frequently much more than just one mistake too, ultimately, dear developer friends, it’s “us” that build mechanisms such as the one behind Tesco’s password recovery system:
You need to proactively help developers understand what these risks involve if you’re to mitigate them in code. Security education for developers is paramount! I’ll come back to the education piece, but let me first draw on some recent blog posts and other non-documented experiences just to put things into context.
The crazy things we do
ELMAH. Need I say more? Actually, ELMAH is a fantastic tool but as I’ve written before, there are a huge number of websites out there with it wide open for anyone to see. It also leaves the potential for session hijacking (among other nasty things) wide open. Just last month I privately disclosed the presence of an unsecured ELMAH log on a UK financial institution’s website! This log was complete with authenticated session tokens so an attacker was about two clicks away from logging themselves in as someone else. These people handle our money! Clearly the developer had simply not configured ELMAH to be accessible by only authorised users
Or how about the case of Westfield shopping centre a little while back? Some of you may recall this convenient little feature:
This is what you got after searching for your license plate on the handy little iPhone app you could use if you lost your car. Actually, the feature was so convenient that you could hit the HTTP services directly and pull back every car in the centre complete with a nice JSON feed of number plates and entry times. You could do this every few minutes if you liked and build a complete profile of shoppers coming to and from the centre by car. You’ve heard of big brother tracking your every move, now it’s a game everyone can play! In this case the developer had wanted to reuse the service for other purposes and it was just more convenient to create one public one that did everything. Convenient indeed.
Another one I was involved in some time back and didn’t share publicly demonstrates the cascading nature of security risks. A particular publicly facing website was accessible only by IP address (no DNS entry) and users deep-linked to a folder within it. When I browsed back to the root, I found directory browsing enabled so you could traverse through the site from the convenience of the browser. That’s bad enough, the directory in the root called “backup” was even worse. The backup folder contained a backup of the entire website including the web.config (this was an ASP.NET site). There was no encryption of sensitive data in the file so the connection string was visible. The SQL Server it was connecting to was publicly accessible and not firewalled off from the world so getting into that was easy. Oh – did I mention the username of the account in the connection string? It was “sa” – Server Admin AKA I now have access to every little thing on this entire SQL instance. This was not a matter of a developer making a simple mistake, this was an organisation that hired developers who simply had no idea what they were doing on many different levels!
Or there are the general discussions I often have with developers such as why it’s still important to secure web services called asynchronously from the browser. Let me paraphrase a typical response:
Even though the API doesn’t have access controls, our users don’t run Fiddler and manipulate requests like you showed us so it’s safe because they can’t see the URL in the browser.
Or how about the times I’ve been told that SSL wasn’t required because they hashed the password on the client then just sent that to the server over HTTP. Or one of my personal favourites, “We don’t need to secure the page because it’s just on an IP address and Google doesn’t index those”. These guys are building our software!
Community support is great (sometimes)
I’m a massive fan of resources like Stack Overflow for learning all about the mechanics of writing software, but it can also be a source of absolute horror at times. Now fortunately the rating system on answers (and questions, for that matter), helps the good stuff float to the top and the bad stuff sink down well beneath the fold, but look at some of these answers and remember that these guys are writing software that I can only assume ends up in the production environments of paying customers:
Take this question about How to make Login Form with Password encryption:
i have my table Account(EmpID,Username, Password). I want to have c# code of login with encryption of password when it save in my database(MSSQL 2008)
Ok, the guy is probably a bit short of being in a position where he should be considering handling credentials, but it’s this answer that’s my real point:
In case the above looks a bit foreign, the “Encryptdata” method, well, doesn’t. What it does is Base64 encodes the password and of course encoding ain’t encryption. This provides absolutely no cryptographic protection whatsoever.
As it turns out, that one was consequently deleted so the next worst one was this:
This is nothing more than character rotation, it’s ROT13, but offset by 5 ASCII values. This also ain’t encryption and also provides absolutely no cryptographic protection.
And then that one got deleted too so then we got this one:
It’s just more character rotation, nothing more. It’s also completely and utterly useless. The entire question was later deleted.
Anyone see a pattern here? This is one question on one forum and the answers are absolutely, well, I’ll avoid saying something derogatory because everyone was just trying to be helpful but this could leave someone in a seriously dangerous security position. And this is all existing code too – I highly doubt the three guys above have just written it out for this purpose, no, they’ve copied and pasted something they’ve already written. Scary.
Now this is not to try and berate the individuals, they don’t know what they don’t know and kudos to them for getting actively involved in the community and trying to help out a fellow dev. In fact they’ve probably learnt something from this themselves (at least the deleted answers would imply that). Regardless, these answers are reflective of many, many similar ones across the web and they do show a prevalence of unconscious incompetence. Just read the news headlines about who’s been hacked today and how simple the attack vector was if you’re in any doubt.
Never underestimate the human ability to do foolish things
A common issue I find when writing about security concepts is I’ll be met with “Duh, who would actually do that?!” as if the concept is just sooo obvious that everyone understands it and silly me for thinking otherwise. Why just last month when I wrote about how stored procedures and ORMs won’t save you from SQL injection I had numerous people say how ridiculously obvious it was – it’s just query and untrusted data concatenation and it doesn't matter that it’s in a stored procedure.
But the thing is that many people don’t understand it and this is why we have questions on Stack Overflow such as Am I immune to SQL injections if I used stored procedures and How to secure dynamic stored procedure. There are many, many more in a similar vein, the point is that for a lot of people, it’s a foreign concept and that’s why the education is important. Keep in mind also that these are just the cases where someone recognises that they might have a problem (the consciously incompetent) – how many more people don’t realise they’re vulnerable or are not even aware of SQL injection to begin with (go back to those earlier Stack Overflow answers)?
But SQLi is one of the easier ones, how about something like insecure direct object references; Citibank developers didn’t know what this was (again, these people handle our money!) Or what about Tesco – they had plain text password storage, emailed passwords, XSS, SQLi, mixed mode HTTPS, broken password validation and a dose of security misconfiguration yet they still insisted that their security was “robust” and “industry standard”.
Now I know many people will look at these example and go, “duh, as if I’d fall for that”. Whilst they’re basic – and equally, whilst these misunderstandings are prevalent – how many people truly understand the risks of most salted hashes? Or the idiosyncrasies of CSRF? Or even the manifestation (and mitigation) or common security misconfiguration? Many more people, no doubt.
Education and now hands on training with QA
So getting back to the education piece, there are a number of different channels I’m trying to provide support on to help developers get up to speed with good security practices. Obviously there’s this blog which is the genesis for most of my material then there’s the free eBook I put out last year titled OWASP Top 10 for .NET developers which has been very popular. I’ve also been speaking where I can on podcasts, at user groups and at conferences plus of course interacting with the community through all the usual channels.
The latest piece of education that I’m very pleased to have been involved with is formal hands-on training by QA via their course titled Developing Secure .NET Web Applications – Mitigating the OWASP Top 10 Security Vulnerabilities. QA is a UK based training organisation and this is four days of intensive classroom training lead by a professional instructor. It goes right through each of the OWASP Top 10 and covers the following for each risk:
- Describes the risk in detail
- Shows how the risk can be exploited (which students then do themselves in the exercises)
- Demonstrates an industry precedent where the risk has led to a serious event
- Applies “security in depth” where the risk is mitigated through multiple defences (also an exercise students do themselves)
During the course students get to experience techniques such as performing SQL injection, cross site scripting and session hijacking. They also get hands on with a bunch of tools such as RainbowCrack, hashcat, Fiddler and Havij. But it’s not all breaking of stuff, there’s lot of building mitigations with the latest generation ASP.NET including taking advantage of security features such as stronger hashing with the SimpleMembership provider, using the AntiXSS library and even a bit of Entity Framework code first to rapidly build whitelists to filter out untrusted data.
If you happen to work in the Java space, QA have also ported the course to that stack and developed Developing Secure Java Web Applications – Mitigating the OWASP Top 10 Security Vulnerabilities.
Regular readers will know that all the educational material I create – regardless of the medium it’s delivered in – has a strong focus on explaining and demonstrating risks before explaining how to fix them. I’m really conscious that there’s a lot of security guidance out there that simply says “STOP DOING THAT” and doesn’t adequately explain why the risk is an issue or exactly how to fix it. In fact that’s why I wrote that Top 10 for .NET devs to begin with – I’d see dedicated security folks without the development background give this advice and be met with a bunch of blank stares by developers and frankly, that really doesn’t really help anyone.
The security education roundup
The QA training is the best way of getting an intensive security education and seriously understanding the risks in depth. It requires a time commitment and it requires a financial commitment but quite frankly, both of these are negligible in the context of what even a minor security incident costs.
Beyond this, the other roundup of 100% free security material you might get something out of includes:
- Written material:
There’ll be plenty more to come and if there’s anything specific anyone thinks would be really valuable to the development community then I’d love to hear about and I’ll try and get it produced in one of the formats above.