When it comes to security of an online business so often we are so used to the concept of an attacker hitting our web server as a main target that we may forget about other important elements of our network, such as our database server. There are many techniques and layers of defense available to protect the external perimeter of the network and web applications. We cannot have too many tools, however, that will protect our data on a database server when an attacker has direct access to the system. That implies that we'll always rely on some other mechanisms to protect our database system, but what if those mechanisms are compromised?
In this example I would like to share one solution that will demonstrate how the database system can be used in detecting the potential unauthorized alteration of the data.
Let's assume we have an online gambling business that relies on our clients accessing web application (an e-casino) which communicates with the backend database. The web application handles user authentication and account management. The database holds information about customer's account: username, encrypted password, name, address, email, and account balance. As a part of our service we offer our clients the ability to associate their accounts with an online payment processing system (such as PayPal) so they can withdraw their funds. To associate the account with PayPal we have to have their email, and name matching PaylPal account information.
The network diagram will look something like this:
Assuming that our web application has the best security practices applied when developed, and our firewall has all the restrictive rules implemented we might think that there is nothing to worry about. However, there is a constant threat of a blackhat community exploiting certain server vulnerabilities and access the database engine directly bypassing our web application. It may be as "simple" as exploiting another buffer overflow vulnerability, which we hear about so many times these days. In this case an attacker may access our database records and modify certain data that will let her impersonate one of the users by replacing her name and email with the original account information.
For example, in the table below, we have 3 users with their corresponding information:
Assuming that "JimK" is a legitimate user, and "ChesterJ" is a phony user created by an attacker "ChesterJ" can replace information used by Payment Processing System to become the owner of the legitimate balance or change his balance with the bogus amount and withdraw funds.
In case of our database system being attacked directly using system specific vulnerability we won't have any signs of a compromise from the web application part. We can use restrictions and triggers, but those can be deleted or altered in no time once an attacker gains access to our DBMS.
The solution to a problem includes simple modifications to our web application and the database.
As we have designed our web applications we know that the only system that is allowed to access the database is an application and its respective user interface.
For example, to create a user we have to use the same old registration screen that is duplicated practically on any website. The same situation is with a system updating user's balance no one can access balance management system unless certain events in an application triggered the change of that balance (for example user won a jackpot etc).
Knowing who's allowed to access certain parts of the database - we can develop custom signatures for our applications that modify user's account. That will include adding one more column to the database that will store unique signature of a modifying application.
For instance, the only time username can be changed is when the user is created through our registration form. Therefore, the registration form will add its hashed signature to the column corresponding to our username. The hash will also include some other important parts of the user's account being unique for every user.
Here are the steps to generate user specific hash in a database:
The registration screen will take down the following information: date user is created (dd/mm/yyyy), username, email, name, and address. The following string is an example of user identification information generated from the input in the registration form: "29/08/2006, 12:39:2368*JimK*Jim K*435 Shell St.*email@example.com". Where "*" is a separator. The string is hashed using SHA1 algorithm (you can use algorithm of your choice) The hashed result (in our case: "0xBB4E951901FF5DCECE446162D2E5B39BE589363F") is recorded to the table along with the rest of the data.
Now that we have created a unique hash for our records any account changes to the information that were not supposed to be made by an authorized application will mean that the data in the database has been maliciously modified. But how do we know that the data has been modified?
There are many approaches to this. We can create a schedule for the user records to be scanned and verified against hash that is in our special column. The scanning is better to be done by another independent system so that when our database is compromised an attacker cannot figure out the hashing algorithm we used along with the string that is expected as an input.
With SQL Server 2005 we can have a scheduled job running any time we prefer comparing original hash value with the one calculated using HASHBYTES (SHA1', @input) function. If the result of our dynamic hash doesn't match the recorded value in a user row the alert is sent to an administrator using Notification Services.
Another approach is to have the integrity of our records checked when it is required. Going back to our e-casino application, whenever user wants to withdraw funds we double check the hash of his current information with the one created earlier.
Of course this solution will not (and should not) replace other security practices available out there. However, it is a nice addition to our multilayer security system.
Feel free to post your comments and feedback here or at firstname.lastname@example.org.