Protect Your Database From Your Webapp

by Chris Josephes

I've been seeing this SQL Server code running wild for the past few days:

DECLARE @T varchar(255), @C varchar(255);
FROM sysobjects a, syscolumns b
WHERE = AND a.xtype = 'u' AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167);
OPEN Table_Cursor;
'update [' + @T + '] set [' + @C + '] =
rtrim(convert(varchar,[' + @C + ']))+
''Explot JavaScript goes here'''
CLOSE Table_Cursor;
DEALLOCATE Table_Cursor;

Actually, the insertion of this code into web servers happens from a DECLARE statement that encodes the entire payload in hexadecimal characters, which is then helpfully translated into exploit code by your own database server. In a way, your SQL Server database hacks itself.

It's been around since January, but the payloads have been different. Either multiple people are using the exploit, or the exploits are modified on a per-hire basis and delivered through the same bot network. One hacker with a client hack pays some other hacker with a server hack, and they go to town. The process attacks hundreds of insecure websites, which in turn attacks thousands of client hosts.

The interesting thing is that this code doesn't really have a catchy name like all of the other exploits. Server exploits never get much attention in the media compared to viruses that attack millions of workstations at once, like Nimda, Melissa, or others.

DBA1: "Hey, did you hear that one website got compromised by 'Column Smasher'?"

DBA2: "No, I thought it was called 'Lemon Pledge'."

DBA1: "Why would a database exploit be called 'Lemon Pledge'?"

DBA2: "Because it cleans everything from your tables."

There have been a few reports of these attacks hitting Cold Fusion servers. Thanks to Google and the .cfm file extension, it isn't too hard to find a Cold Fusion server out there. And if someone is using Cold Fusion, they're probably just coding in CFML, which isn't a very robust language.

Remember FormMail? Formmail was that horrible CGI script that everyone abused to send out spam. Well, it seems like people haven't taken the hint. All that information passed from a web client to the server through a GET or POST method should be considered dangerous. Web page constraints, JavaScript/AJAX validators, and hidden form fields can't protect your database. Depending on how your web forms and server applications are written, you're allowing outside input from unknown sources to be inserted into the middle of your humble SQL statement. The most important firewall to protect your database is your server side application.

Here's a few things you can do to protect your database from SQL injection attacks. Suggestions 1 through 3 range from low level sanitation to high level extreme SQL programming. Suggestion 4 is geared more towards administrative efforts for a Database Administrator to protect their system from a web developers badly programmed application.

1. Sanitize the input. Run regular expresison filters that will ideally work on a pattern of allowed characters, Accept only alphabetical characters and numerals, but strip everything else out.

2. Use SQL bind variables to contain web application input, after it's been filtered.

3. Using stored procedures can give you the benefit of limiting what statements your web application can execute on the database server. Keep in mind that stored procedures are still pretty complex, and unless they're coded properly, they may not add additional security from the application.

4. Block select privileges to the sysobjects and other system tables. And just because you're not running SQL Server, don't assume you're in the clear. Check with your DB vendor to see specific instructions on how your server handles the Information Schema portion of the SQL-92 standard.


Anonymous coward
2008-07-26 05:44:33
It seems we are running short of ideas for decent sysadmin articles...