OWASP is a non-profit organization with the goal of improving the security of software and the internet. They have put together a list of the ten most common vulnerabilities, which we will cover one by one in this blog series. This is the first post, and you will be able to find the rest by clicking here.
The first one on the list is Injection. This type of finding is more like a category, and includes all kinds of vulnerabilities where an application sends untrusted data to an interpreter. It is often found in database queries, but other examples are OS commands, XML parsers or when user input is sent as program arguments.
This is a very common vulnerability type, especially in legacy code as it was way more common a few years ago when fewer were aware of the danger. SQL-injection is to be considered the most known injection type, and according to a survey conducted by Ponemon 65 percent of the organizations represented in the survey had experienced a SQL-injection attack in the prior 12 months. That research was published two years ago, but should still be able to be used as an estimation.
As it is a very broad category of a vulnerability, the danger varies greatly from case to case. As SQL injection is the most known injection-type, the impact is often stolen data from a database. That can include usernames, password and other sensitive information.
The worst-case scenario would be a full takeover of the system, which certainly is possible depending on where the injection is and in what environment.
It is an attack that can be automated, which puts you at higher risk. An attacker does not need to be after you, they can simply write a script that exploits as many sites as possible and yours being one of them is a coincidence.
A few famous/infamous events involving SQL-injections specially can be found on Wikipedia,
One of the most known attacks done by SQL injection was targeted against Sony. Another almost ironic one was when MySQL themselves suffered from an SQL-injection. As can be understood from the examples, big players are also at risk and the result of an attack can be terrifying.
How to discover
For more advanced users it is a vulnerability that can often be found while doing code analysis. Ie., identifying all queries in the web application and following the data flow. As it sometimes generates no visible feedback it can be hard to detect during a blackbox-test, even though it often is possible as well.
This is also a vulnerability that Detectify scans for, so the easiest answer would of course be to scan your site using our service. We offer a 14-day trial, so there are no downsides to at least trying it out!
As Injection is a very broad definition it varies from case to case, but a general classic SQL-injection is very easy to exploit. Troy Hunt once uploaded a video of him teaching a three year old to exploit an SQL-injection to demonstrate that really anyone can learn to exploit this kind of vulnerability.
Code example of vulnerable application
A typical example of a SQL injection would be in a login form, with the code shown below:
$db = new mysqli('localhost', 'root', 'passwd', 'base'); $result = $db->query('SELECT * FROM users WHERE user="'.$_GET['user'].'" AND pass= "'.$_GET['password'].'"');
Suppose the attacker submits “ OR 1 — as username and whatever as password the whole query will end up looking like this:
SELECT * FROM users WHERE user="" OR 1 -- AND pass="whatever"
Everything after — (which indicates the start of a comment in SQL) will be discarded and ignored. The query to be executed would then look like this:
SELECT * FROM users WHERE user="" OR 1
The query now states “Grab everything (SELECT *) from the user list (FROM users) where the username matches nothing (WHERE user=””) or 1 (which will be interpreted as True (OR 1))”.
Since the latter statement will always result in True, the right hand of the statement will successfully eliminate the left hand statement and the condition will always be true. The result of that query would be the same as this one:
SELECT * FROM users
Which would return all data there is about all the users. Eg., the injection in the $_GET[‘user’]parameter is enough to make the MySQL server to select the first user and grant the attacker access to that user.
1. As Injections is more of a category of vulnerabilities, the remediation varies from case to case depending on what kind of vector and interpreter we are talking about. The optimal solution is to use an API which either avoids the interpreter or provides a parameterized interface.
Parameterized queries are not hard to do, and if you use PHP we would recommend PDO. It may sound strange at first, but it really is not as hard as you may first think. Examples in other languages can be found here.
2. If parameterized queries are not an option in your case, you should instead carefully escape special characters. How this is done depends on the interpreter used, and something you would need to look up.
3. Whitelist input validation is also an alternative, but often cannot be used as the application can require special characters as input. For example, a blog wants to allow its visitors to make comments using quotes, even though that is a character that could be used to break out from a query. In those cases it is necessary to go with solution one or two.
Other injection types we have mentioned:
How Patreon Got Hacked: Publicly Exposed Werkzeug Debugger
How We Got Read Access On Google’s Production Servers
Top 10: Injection
Linus Särud, Security Researcher