The OWASP organization lists “injection” attacks as the number one security flaw on the Internet today. In fact, injection attacks have made the OWASP top ten list for the past 13 years and have been listed as the number one attack for the past 9 years. Needless to say, these attacks are serious business and should be guarded against very carefully.
Every web application environment allows the execution of external commands such as system calls, shell commands, and SQL requests. What’s more, almost all external calls can be attacked if the web application is not properly coded. In the general sense of the word, an injection attack is one whereby malicious code is “injected” into one of these external calls. These attacks are typically used against SQL, LDAP, Xpath, or NoSQL queries; OS commands; XML parsers, SMTP Headers, program arguments, etc.
When a web application passes information from an HTTP request to an external system, it must be carefully scrubbed. Otherwise, the attacker can inject malicious commands into the request and the web application will blindly pass these on to the external system for execution.
One of the most common types of injection attacks in a SQL injection. Many web applications utilize a backend database to store critical information like usernames, passwords, credit card numbers, personal information (address/phone number), etc. When you login to a website, you present your authentication credentials (i.e. username/password), and something on that backend has to validate that you are the correct user. There’s a database back there somewhere holding all that information. In effect, what has happened is that the website you are logging into sent an external command to a backend database and used the credentials you provided in the HTTP request to validate you against the stored database information.
Along the way somewhere, some malevolent peeps had some crazy thoughts that went something like this: “hey, if my HTTP request is going to ultimately populate a SQL database command, maybe I could supply some crazy info in that HTTP request so that the SQL command ends up doing some really wild things to that backend database!!” That’s the idea behind the SQL injection attack.
SQL commands are used to manipulate database information. You can add, delete, edit, display, etc any information in the database. Like any other system commands, these can be very helpful or very dangerous…it just depends on how they are used. Of course, these commands need to be locked down so that only trusted administrators can use them when running queries on the database. But imagine a web application that wasn’t built correctly and it allows SQL commands to be passed from the HTTP request to the backend database with no error checking at all. That would be a ripe web application for an injection attack!
The screenshot below shows a web application for an online auction site called “Hack-it-yourself auction”. This is a fictitious site that was purposely built with bad coding techniques and tons of vulnerabilities. It provides a great testing venue for things like injection attacks. It also showcases the power of a Web Application Firewall (WAF) and the protection it can provide even when your web application is totally vulnerable like this one.
Notice in the screenshot that a user can login to the auction site via the “username” and “password” fields on the right side of the page.
When a user submits login information on the website, the HTTP request takes the values from the “username” and “password” fields and uses them to formulate a SQL command to validate the user against the backend database that stores all the user information (name, address, credit card number, etc).
The SQL command is designed to look something like this:
SELECT id FROM users WHERE username = “username” and password = “password”
This SQL command grabs the values for “username” and “password” that the user typed into each of those fields. If the username and password are correct, then the user is validated and the web application will allow the user’s information to be displayed.
A SQL injection takes advantage of the fact that the HTTP request values are used to build the SQL command. An attacker could replace the “username” info with an interesting string of characters that don’t look very normal to the casual observer but are still understood by the backend database. Check out the screenshot below to see the unique SQL injection username.
In this example, the username is ‘ or 1=1# and that will result in the SQL statement looking something like this:
SELECT id FROM users WHERE username = ‘’ or 1=1# and password = '".md5($MD5_PREFIX.$password)."'
Essentially, this statement is asking the database to select all records in the users table. It takes advantage of the fact that the web application is not validating user inputs and it uses the "or" expression on the username and then states a fact (in this case, 1=1) so that the database will accept it as a true statement. It also uses some creative MD5 hash techniques to access the password. Notice the username in the screenshot below:
Apparently this SQL injection worked because now I am logged in as user ‘ or 1=1#. Not your typical, everyday username! So, the authentication was allowed to happen and the database is now ready to serve up any and all records that are located in the users table. I wonder what kind of goodness we can find there? Notice the “Your control panel” link on the page…that link takes you to the information stored for each user in the database. The database is ready to serve up ALL the records in the users table, so let’s click on that “Control Panel” link and see what kind of goodies we can find. Check out the screenshot below and notice in the address bar a familiar-looking username at the end of the URL:
Clearly we have some serious issues here. At this point, the attacker has all the names, credit card numbers, emails, phone numbers, and addresses of every single user of this auction site. The attacker could simply copy all this information and use it later or he could manipulate it using other SQL commands or he could delete it all…the possibilities are seemingly endless. Think about some of the recent data breaches you’ve read about (or experienced) that have disclosed sensitive information…some of them happened because of a situation very similar to what I’ve just shown above.
The correct answer for this problem is to fix the code that was used to develop this web application. Obviously, this specific code doesn’t check for valid usernames…it will pass along anything you put in that field. OWASP has a list of proactive controls that are great techniques to help prevent exploitation of one or more of the OWASP top ten vulnerabilities. For injection attacks specifically, code developers should do things like parameterize queries, encode data, and validate inputs. Ideally, code developers will write phenomenal code and you won’t ever have to worry about these vulnerabilities. And, in recent years, developers have done a great job of using secure coding practices to do just that. However, not all developers are perfect, and some of the code we use today is very old and hard to change…it’s also full of security vulnerabilities that allow for things like SQL injections.
The BIG-IP Application Security Manager (ASM) is a Web Application Firewall (WAF) that protects your web applications from attacks like the ones listed in the OWASP top ten. While it’s true that code should always be developed in a secure manner, those of us who live in the real world understand that we can’t rely on the hope of secure coding practices to protect our critical information all the time. That’s why you need a WAF. In the case of the very vulnerable “Hack-it-yourself auction” site, a WAF will protect the web application when it cannot protect itself. In the case of a SQL injection, a typical network firewall would have never blocked that attack because it was, in fact, a valid HTTP request on an open port (80, in this case). However, a WAF will inspect the HTTP request, notice that something isn’t quite right, and block it before it ever has a chance to do any damage to your backend database.
I created a security policy using the BIG-IP ASM and then turned it on to protect the auction site. The ASM now sits between the user and the web application, so every HTTP request will now flow through the ASM before it heads over to the website. The ASM will inspect each request and either let it through or block it based on the configuration of the security policy. I won’t go into the details of how to build a policy in this article, but you can read more about how to build a policy here.
After the security policy was created and activated, I tried the same SQL injection again. This time, instead of getting access to all those credit card numbers, I got a screen that looks like this (you can manipulate the screen to say whatever you want, by the way):
Clearly the ASM is doing its job. Another cool thing about the ASM is that you can review the HTTP request logs to see exactly what an attacker is attempting to do when attacking your web application. The screenshot below shows some of the details of the SQL injection attempt. Notice the “Detected Keyword” portion of the screen…see anything familiar?
Stay tuned for more exciting details on how the ASM can protect your web applications against other OWASP top ten (and more) vulnerabilities!