By Brigette Currin 4 minute read

I aim to post series of blog posts looking at the Open Web Application Security Project (OWASP) Top Tenweb application risks.

These really are the obvious attacks that all web developers should be aware of, and know how to code to prevent.

The OWASP Top Ten does not account for Trojan horses, Viruses and other more complex or contrived attacks; It only accounts for attacks on web services and servers, and would likely need to be incorporated into a larger ‘attack’ to reveal and technical or business impact.

It is, however, a good starting point if you want to have some level of assurance that your web application is, at a baseline, secured.

THE FIRST RISK DESCRIBED IN THE OWASP TOP TEN IS INJECTION

The Injection attack comes down to correctly and thoroughly sanitising all input provided by a user. If you don’t validate that the input provided by a user is correctly formatted, then you could inadvertently execute code or expose data you didn’t anticipate exposing.

Imagine the following pseudo-code that might be part of a script on a web application:

FindAccount($request)
{
   $findAcctSQL = “SELECT * FROM accounts WHERE ID = “ + $request.getparameter(“customerID”)
   $acct = $Sql.execute($findAcctSQL)
   return ($acct)
}

So one might imagine that this code is used to collect the account details for a given customerID. Under normal conditions the user enters the customerID from a dropdown list of those he’s permitted access to.

But the findAcctSQL string is just a concatenation of the SQL command with the unsanitized request parameter. We expect that parameter to simply be a customerID number… but what if it’s not?

What if instead of customerID being equal to “345” or “’Acme Corp’”, we put SQL in that parameter itself? Say we put “7 OR 1=1;”. The “7” part is actually irrelevant, it just meets the SQL syntax requirements. But we can now lead the SQL interpreter to evaluate the next part of the statement, which will always be true… (“OR 1=1”) for all lines in the table.

So, when executed, this injection will spill the entire accounts table into the $acct variable, ready to be printed to the screen or have some other operation applied!

Maybe not disastrous, but certainly not what we expected this function to do.

Or perhaps we put “7 UNION SELECT * FROM Users”. We’re now selecting data from an entirely different table and concatenating it to the back of our accounts table select statement, so are able to collect data from other parts of the database. Again, probably not what we wanted this function to do.

Or maybe “7; DROP accounts;”. Yikes! This is getting dangerous!!

So how do you protect against this type of risk?

If we know we’re expecting a single integer number as the customerID (for instance), then we should wrap our getparameter call in a toInteger call to force the value to be an integer. Under normal conditions, this will make no difference to the execution of the application, but where our nasty attacker is crafting special SQL commands, the toInteger will likely throw an exception (which we can now gracefully handle) or in the worst case return zero. So our pseudo code becomes:

FindAccount($request)
{
   $sanitizedCustomerID = toInteger($request.getparameter(“customerID”))
   if($sanitizedCustomerID <> 0)
   {
      $findAcctSQL = “SELECT * FROM accounts WHERE ID = “ + $sanitizedCustomerID
      $acct = $Sql.execute($findAcctSQL)
      return ($acct)
   }
   else
   {
      $log.println(“SQL Injection Attempt : “ + $request)
      return(null)
   }
}

This may all seem very contrived, but this type of injection vulnerability is amongst the most common web application vulnerability out there in the wild. It’s incredibly easy to attack, and annoyingly simple to protect against. Sanitizing user input is Computing 101, and there really should be no excuse for processing any unsanitized user input.

Detecting this vulnerability in your web applications after they have been developed can be a bit tricky, as obviously there are going to be lots of ways that a user can input data into your system.

Using a fuzzer can be a long winded way of discovering this type of vulnerability in your own web application, better to use a input sanitiser pattern in your code where users are able to input any data into your application.

Next Time: Broken Authentication and Session Management

Join the conversation on Twitter @JJSecurityGuy @KCOMbusiness #crypto #infosec

First published in 2015 by KCOM. Reproduced with permission.

Jonathan Jenkyn

Jonathan leads the security practice at KCOM where he brings to customers his experience working in across banking, broadcast, government and defence sectors since 1999, specializing in the analysis, design and development of security solutions, leveraging leading edge cryptographic technologies.