30 Dec, 2019

SQL Injection: An Invisible and Dangerous Hacking Attack

Web applications have at least one SQL injection vulnerability. Here’s what you need to know about SQL injection, and how to protect your website.
Web applications work with databases to store and retrieve information. Most of them use SQL, or Structured Query Language, to retrieve, add, and change information. SQL is a programming language specialized for databases. A Web application constructs an SQL statement to request or enter information. Pre-written pieces of SQL come together with user inputs to build the statements.
So then what exactly is SQL injection?

Malicious user inputs can result in SQL statements to do things that the application's creator never intended. Without adequate website protection, these queries can retrieve or enter data in unauthorized ways. Year after year, injection vulnerabilities have been at the top of the OWASP Top 10 application security risks. Studies have shown that about 28% of Web applications have at least one SQL injection vulnerability. Some of the largest data breaches in history have been due in part to injection issues.
SQL and Web applications
A typical scenario has the user fill out a form on a browser. For instance, the form could request the visitor's name, address, and email. The values from these fields become part of the query, which could look like this:
INSERT INTO CONTACTS (FIRST_NAME, LAST_NAME) VALUES ('John', 'Smith');
That creates a new row in the CONTACTS table with the name that was given. Other SQL statements retrieve, alter, or delete existing information.
How SQL injection works
If the inputs are legitimate, everything works correctly. Malicious inputs can trick the SQL engine into accepting additional statements, which are whatever the attacker wants them to be. These are known as SQL injection attacks. The usual way to do this is to add a delimiter. Suppose that instead of "John," the first name entered is:
John', 'Smith''); DELETE FROM CONTACTS
Then instead of one SQL statement, there will be two:
INSERT INTO CONTACTS (FIRST_NAME, LAST_NAME) VALUES ('John', 'Smith'); DELETE FROM CONTACTS
This code, if it's executed, will remove everything from the CONTACTS table.
Another way to foment chaos is to add a condition that will make an operation affect all rows of the table rather than just one. This statement will check a user ID:
SELECT * FROM CONTACTS WHERE USER_ID = '7AX254'
With an extra test tacked on, it will bypass the check:
SELECT * FROM CONTACTS WHERE USER_ID = '7AX254' OR 1=1
The expression "1=1" is always true, so the statement always passes the test regardless of the USER_ID value.
The reverse technique is to hide something from the SQL parser by inserting "--", which says that the rest of the command is a comment and shouldn't be executed. That could be a way to bypass a password check:
SELECT * FROM USERS WHERE USER_ID = '12345' -- AND PASSWORD = 'password'
That statement was designed to check the password as well as the user ID, but injecting a comment delimiter removes the password check. (That statement is bad coding practice for other reasons, but this is just an example.)

Web applications need to guard against injection by "sanitizing" their inputs. They need to look for characters that shouldn't be there and either filter them out or reject the whole input. If an application developer forgets in just one place, that opens up a vulnerability.

JavaScript to prevent invalid entries in a form isn't enough. An HTTP request simulating the form entry can be generated manually and sent to the victim's server, bypassing browser checks. The best practice is to use server-side code libraries that check their inputs.
Injections in disguise
Hostile queries are often disguised to get past filters and firewalls. Here is an example of an injection attack against a Quttera customer, which we detected.
It has been modified so it doesn't do anything dangerous, but it could just as easily be one that dumps the content of a table. A form parameter included the following:
%28SELECT%20CHAR%28113%29%2BCHAR%28107%29%2BCHAR%28122%29%2B
CHAR%28113%29%2BCHAR%28113%29%2B%28
SELECT%20%28CASE%20WHEN%20%289814%3D9814%29%20THEN%20CHAR%2849%29%20ELSE%20CHAR%2848%29%20END%29%29%2BCHAR%28113%29%2B
CHAR%28120%29%2BCHAR%28118%29%2BCHAR%28120%29%2BCHAR%28113%29%29
Decoded, it becomes:
SELECT "q" + "k" + "z" + "q" + "q" + (SELECT(CASE WHEN(9814 = 9814) THEN "1" ELSE "2" END)) + "q" + "x" + "v" + "x" + "q")
Notice the use of "WHEN(9814 = 9814)", which is always true but adds obfuscation. Only a sophisticated WAF, such as ours, will catch SQL injections that are so heavily disguised.
Following are the two other malware examples
Quttera's Web Application Firewall detecting SQL injection, this time not encoded:
Quttera Firewall detecting injection with the shell script inside:
Why SQL injection is so dangerous
The effect of an injection attack is immediate, and it can be highly damaging. It opens up several kinds of dangers:
  • Pulling information out of the database, including personal financial information. Data thieves can sell it on the black market.
  • Bypassing authorization checks by altering the logic in a conditional query.
  • Vandalizing the database, removing information or replacing it with nonsense.
  • Changing values, e.g., increasing the balance in an account or reducing the amount due.
  • Adding entries. An attack could make the perpetrator an authorized administrator or add a spy to a confidential mailing list. This can be a first step toward installing malware on the server.
An invisible attack
Unlike most attacks, SQL injection doesn't involve putting anything on the target's Web server. The entire attack is contained in the malicious query. Anti-malware software is useless against it.

If it's used just to export information from the database, there are no signs that anything bad has happened. At best, a thorough examination of the logs for the server and database will show some unusual queries. If administrators notice damage to the database, they won't find any malware to account for it.
Website protection against injection
The first line of protection against SQL injection is good coding practices. Developers should rely on well-tested code libraries rather than generating SQL statements directly. That will prevent the vulnerability from happening.

Penetration testing is valuable in catching vulnerabilities. Checking all form fields with SQL injected attempts will catch many flaws before the code is released to the public.

Database accounts should run with only the privileges needed for the job. For example, a Web application normally doesn't need to create or delete tables or to shut down the database, so it should use an account that can't do these things.

Databases should encrypt their most sensitive fields. If an attack exports them, the thieves will get only encrypted credit card numbers and hopefully be unable to crack them.
SQL vulnerabilities are often caught and fixed after the initial release, and administrators should keep their software up to date with all security patches. This helps to protect websites against all kinds of vulnerabilities.

Sometimes these risks go uncaught for a while, but having a web application firewall (WAF) will stop attackers from exploiting them. The Quttera WAF checks all incoming HTTP requests and blocks SQL injection and other malicious packets. The WAF is available as part of Quttera's comprehensive ThreatSign website protection service. With ThreatSign working for you, your database is safer and your business will run into fewer problems.