The operator of a website who accepted user logins on unencrypted HTTP pages hit the news this morning (in a bad way), after taking to Mozilla’s bug tracker to complain that the Firefox browser warns his customers that their data is being sent insecurely.
— Eric Mill (@konklone) March 20, 2017
In itself, it’s a funny story about how to spectacularly miss the point about web security, and possibly a sign of things to come as website operators struggle to keep up with browsers tightening security standards. But what followed was a spectacular example of what can happen if you don’t take information security seriously. Their site, oilandgasinternational.com, is down at the time of writing this. According to a number of sources, their database has been compromised and destroyed due to an SQL injection attack. Their user passwords were stored as plain text. Aside from the obvious lessons (like making sure you account for Little Bobby Tables), below are some of the things we might want to learn from them.
1. Your past security performance is no guarantee of the future
We have our own security system, and it has never been breached in more than 15 years
It’s an impressive claim (even though today they reset that counter to zero). But complacency has no place in software development. The landscape of web technologies is constantly evolving, with new vulnerabilities being discovered and the tools to exploit these vulnerabilities become more sophisticated and available. It’s not just technical factors in play, either – threat likelihoods and the impact of an intrusion depend on considerations such as your site’s popularity and demographic. Given the scale of vulnerabilities, it seems likely that was the factor in play here – it hasn’t been compromised before today simply because no-one was interested enough to try.
2. Attacks happen. Sometimes they succeed. You need to mitigate them.
The last few years have seen a large number of high-profile data thefts, notably LinkedIn and Yahoo. The unfortunate truth is that sometimes intrusions are successful. Closing vulnerabilities and protecting against threats is only half the battle – in order to protect user data fully, you need to start with the assumption that the data will be breached, and take steps to mitigate the impact of this breach. First up: passwords should never, ever be stored as plain text. They should be hashed and salted using a strong one-way encryption algorithm. If you see anything like this, it should be an immediate red flag.
Second: limit application DB access so it can’t drop tables. More on that later.
Third: Have a backup in place. Make sure it works.
3. Don’t disclose information about your system
According to discussion on Reddit, the site was returning detailed error messages, including stack traces, version information, and source code snippets.
This is called information disclosure. It’s a big deal because the more information an attacker knows about your system, the easier it is for them to find vulnerabilities. For example, by knowing the web server vendor and the version, they are able to search for known issues with that version and potentially exploit them. In the above image, it also details clearly that the login form is not sanitising database inputs and is therefore vulnerable to an SQL injection attack.
Worse still, these error messages were apparently so verbose that they revealed a user’s password in plain text! According to Reddit user WeRequireCoffee, an error message containing the password could be produced by forcing the text password field to be compared to an integer:
It’s important to make sure that error messages sent from the application are sanitised before being sent to the user, so that they are informative but contain no implementation data or user data. Debug error messages should absolutely be turned off in production environments. Where possible, default web server error messages containing version numbers should be replace with generic ones. The same goes for version strings in HTTP response headers.
4. Access control is very, very important
There are 3 main things to consider in information security: confidentiality, integrity and availability. The SQL injection attack allegedly allowed attackers to retrieve data they weren’t ordinarily allowed to view: this is a breach in confidentiality.
This would be serious enough in terms of reputational damage and loss of customer trust, but there are reports that attackers were able to successfully delete database data and drop database tables: a loss of availability. If this is true, and there are no backups, the impact of the attack is considerably worse – and let’s face it, if a company wilfully ignores security issues and stores passwords in plain text, the chances of there being a robust backup policy isn’t great.
An SQL injection attack, though serious, should not be able to drop database tables. The connection between the site and the SQL database should not have privileges to alter the structure of the database. It’s a good rule of thumb to always limit access of applications (and users) to the minimum possible that it needs to do its job.
5. For the love of God, don’t advertise your vulnerabilities in a public forum
The internet is not kind. Do risk assessments internally, but never let them see you bleed.