Quote

"Between stimulus and response there is a space. In that space is our power to choose our response.
In our response lies our growth and freedom"


“The only way to discover the limits of the possible is to go beyond them into the impossible.”


Friday 8 August 2014

How to look at application security, Top-Down or Bottom-Up?


As a software professional I have been infatuated to application security more than once in my career purely out of interest as none of the assignments directly held me responsible for application security.

The more I tried to understand the subject top-down the more slippery and complex it appeared. After many slips I realized it is a subject better understood bottom-up. You need to first understand a specific vulnerability in a piece of code and how it can be exploited by hackers. Then keep running through the list of vulnerabilities and break them one by one.

Once you have the dots of the vulnerabilities solved you need to connect them to see the holistic framework of application security. I personally found this approach less fuzzy than trolling through endless definitions, tools, tips and tricks.

So let us begin with some vulnerable pieces of codes and analyze them to see how they can be exploited by hackers.

Code Block 1:


String objectCount =  request.getParams("ObjCount");
int numObjCount = Integer.parseInt(objectCount);
ObjectArray [] arrayofObjects = new ObjectArray[numObjCount];

This code works fine functionally and should not cause an issue until exploited by a hacker to build a huge array whose size is determined by a request parameter. A huge number passed as a parameter which is used for determining the array size can lead to memory leaks and consequently DoS (Denial of Service) type of attacks.

A simple check can deny a hacker the potential to exploit the vulnerability:

String objectCount =  request.getParams("ObjCount");
int numObjCount = Integer.parseInt(objectCount);
if(numObjCount <= protectedAcceptableNo)
ObjectArray [] arrayofObjects = new ObjectArray[numObjCount];


Code Block 2:



class CustomerDAO {

    … …

   public void createCustomer(CustInfo cust) 

                 throws CustCreationException {

       … …

           try {

            Connection conn = DAOFactory.getConnection();

            CallableStatement  calaStmt = conn.prepareCall(…);

          …  …             

           calStmt.executeUpdate();

           calStmt.close();

          conn.close();

       }  catch (java.sql.SQLException e) {

            throw CustCreationException (...);

       }

    }

}

As we can see in the code block above the connection is closed in the try block. If  a SQLException happens before the close() call then the connection will not be closed. If an attacker comes to know about this vulnerability, they can exploit it by sending multiple requests that result in SQLExceptions and hence exhausting the connection pool. A small change can make the code secure from such attacks.

class CustomerDAO {

    … …

   public void createCustomer(CustInfo cust) 

                 throws CustCreationException {

       … …

           try {

            Connection conn = DAOFactory.getConnection();

            CallableStatement  calaStmt = conn.prepareCall(…);

          …  …             

           calStmt.executeUpdate();

           calStmt.close();

          conn.close();

       }  catch (java.sql.SQLException e) {

            throw CustCreationException (...);

       }finally{
       if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) { /* ignored */}
    } 
}

    }
}

The above two examples show how gaps in code can be used to exploit and perpetrate DoS type of attacks on an application. In subsequent posts I will try to bring more vulnerable code examples to demonstrate different type of security threats. However the moot point that I wanted to drive is that: Application security risk mitigation or a contingency plan is better prepared using a bottom up approach instead of a top down approach.