Welcome to Secumantra! We already learnt what is OWASP and OWASP Top Ten in our previous post. OWASP Foundation is one of the most respected authorities in the field of web application security and it releases OWASP Top Ten List periodically sharing most common security vulnerabilities.
Injection is the number one vulnerability mentioned in OWASP Top Ten 2017. It can can have very severe consequences. An injection attack happens when untrusted data is sent to an interpreter as part of a command or query with an intention to do something that the application was not supposed to do.
It may come from any injection flaws, such as SQL, NoSQL, OS, and LDAP injection. SQL injection is the most widespread form of injection and is typically talked about, but injection is not always SQL injection.
Attacker’s primary goal here is to find a way to run his own code on your web server. It will help him to get valuable confidential data or probably can corrupt the data from server.
Let us look at the OWASP risk rating matrix –
The most common vulnerability in the form of injection is SQL (Structured Query Language) injection. This technique is used to modify or retrieve data from SQL databases. By inserting specialized SQL statements into an input field, an attacker is able to execute commands that allow for the retrieval, manipulation or destruction of sensitive data from the database.
With this technique, the unauthorized user is able to spoof the identity of a more privileged user, make themselves administrators and tamper or destroy the sensitive data.
In web applications, SQL injection typically occurs over the Internet by sending malicious SQL queries to an API endpoint provided by a website or service. In its most severe form, SQL injection can allow an attacker to gain root access to a machine, giving them complete control.
How does a SQL injection attack work?
SQL query field that is supposed to be reserved for a particular type of data, such as a number is instead passed unexpected information, such as a command. The command, when run, escapes beyond the intended confines, allowing for potentially evil behavior. A query field is commonly populated from data entered into a form on a webpage.
Lets’s imagine we have a website URL like – http://www.somebank.com/accounts?custId=1001
Expected SQL Query
Let’s look at an example –
String query = "SELECT * FROM accounts WHERE custID='" + request.getParameter("id") + "'";
In this normal SQL query, the custId string is passed into a SQL statement. The goal is to look through the list of accounts for an account that matches the custId entered. Once found, that customer’s record will be returned. Put simply, the command says “go find this user and give me their data”.
If a customer enters a user ID of 1001 inside a webpage form labelled ‘Please enter your user ID’, the resulting SQL query will look like:
SELECT * FROM accounts WHERE custId = 1001;
This command will return the record for the particular user with a custId, which is what the developer who wrote the API expects to happen.
SQL Injection Query
In the above example, an attacker can instead enter a SQL command or conditional logic into the input form field: 1001 OR 1=1
Normally the query would search the database table for the matching ID, but now it looks for an ID or tests to see if 1 is equal to 1. We can see that the statement is always true for every user in the column, and as a result, the database will return all data from the accounts table back to the attacker.
Actual query looks like –
SELECT * FROM accounts WHERE custId = 1001 OR 1=1;
How to prevent SQL injection?
Preventing code injection vulnerabilities really depends on the technology you are using on your website. For example, if you use WordPress, you could minimize code injection vulnerabilities by keeping it to a minimum of plugin and themes installed.
If you have a tailored web application and a dedicated team of developers, you need to make sure to have security requirements your developers can follow when designing and writing software. This will allow them to keep thinking about security during the lifecycle of the project.
OWASP’s recommends following preventive measures against SQL injections.
- Use Safe APIs (Parameterize SQL Statements) – The preferred option is to use a safe API, which avoids the use of the interpreter entirely or provides a parameterized interface, or migrate to use Object Relational Mapping Tools (ORMs). Main idea behind preventing injection attacks is to keep data separate from commands and queries. Additionally each parameter is type casted.
- Input validation – Use positive or “whitelist” server-side input validation. Whitelist tells us what data is a good data, so everything else is untrusted data. This is not a complete defense as many applications require special characters, such as text areas or APIs for mobile applications.
- Escape All User Supplied Input – For any residual dynamic queries, escape special characters using the specific escape syntax for that interpreter. To circumvent users who enter these characters either accidentally or maliciously into an API request to the database, user supplied input can be escaped. Escaping a character is the way of telling the database not to parse it as a command or conditional but instead treat it as literal input.
- Use of Stored Procedures – Although not a robust security strategy by itself, stored procedures can help limit the risk associated with SQL injection. By properly limiting the permissions of the database account running SQL queries, even non-robust application code that is vulnerable to SQL injection will lack the permissions necessary to manipulate unrelated database tables. Stored procedures may also check the type of input parameters, preventing data to be input that violates the type the field is designed to receive. In instances where static queries are insufficient, stored procedures are typically to be avoided.
- Enforce Least Privilege – As a general rule, in all instances where a website needs to use dynamic SQL, it is important to reduce the exposure to SQL injection by limiting permissions to the narrowest scope required to execute the relevant query. In its most obvious form, this means that an administrative account should in no instance be executing SQL commands as a result of a API call from an unauthorized request. While stored procedures are best utilized for static queries, enforcing least privilege can help reduce the risks of dynamic SQL queries.
As a best practice, several strategies should be utilized. Remember defense in depth while dealing with a security vulnerability.
SQL injection works by targeting a vulnerable Application Programming Interface or API. An API in this case is the software interface through which a server receives and responds to requests.
There are tools easily available that allow an attacker to automatically search through a website looking for forms, and then attempt to input various SQL queries that may generate a response that the website’s software developers did not intend in order to exploit the database.
SQL injections are easy to implement, and interestingly, also fairly easy to prevent given the proper development practices. A single vulnerable field on any form or API endpoint across a website that has access to a database may be sufficient to expose a vulnerability.
Injection (particularly SQL injection) is extremely serious risk that needs to be approached very carefully when developing web applications. Anything that accepts parameters as input can potentially be vulnerable to a code injection attack. So validating and/or sanitizing user-submitted data will be helpful to avoid such risks which can be achieved by applying secure development practices or using right kind of ORM framework.
Thank you for reading. Stay Safe, Stay Secure!