I’ve been reading up on the mass SQL injection attack launched against servers running IIS and MS SQL Server last week. That article is a bit out of date, as the problem turned out not to be a security hole in IIS but rather security holes in the Web applications themselves. The script that compromised the sites was clever enough to probe for forms that didn’t prevent SQL injection, and injected SQL specifically designed to work with MS SQL.
The article linked to also says that the attacks were first reported on April 17, but I found an incident report from April 13 describing the attack.
IIS.net has a post that explains exactly how the attack works. The script finds a form on the site that does not properly escape user input and injects SQL that finds all of the text columns in the database and appends the HTML that loads the malware to each of them. You can read more about it here. The main innovation in this attack is the cleverly written SQL injected that’s ejected. A similar attack could be launched against any application that does not protect against SQL injection. MySQL is somewhat protected in that most sites are running MySQL 4.x, which doesn’t provide support for stored procedures.
There are several takeaways from these attacks:
- The only common vector in these attacks is MS SQL Server. Any application that does not prevent SQL injection could be the vector. So a Java application running on Solaris or a PHP application running on Linux could also be affected if they store their data in MS SQL.
- You should minimize the privileges granted to the database user that the Web application uses. If your application uses the “root” or “sa” account, give up now. Just using
grant allis the wrong idea for a production account. Figure out which privileges the account must have for your application to work properly, and grant only those.
- If you’re writing Web applications and you’re not sanitizing user input, you need to go back to the drawing board. I’m beginning to think that languages like PHP and libraries like J2EE should sanitize all input by default and force programmers to go out of their way to access the original input. In other words, in PHP,
$_REQUESTshould contain escaped data by default. Many programmers don’t know what they’re doing, and in the case of attacks like this one, it’s end users who get hurt, not just the people who wrote the compromised application.
- Just visiting Web sites you trust isn’t enough to keep you safe. Keeping your PC patched up and running security software is essential to preventing your PC from being compromised. It just keeps getting more dangerous.
- Replication and backup are two different things. When this attack was run, all of the bad information inserted by the attack was almost certainly copied to the replication server immediately. Taking a snapshot of your data frequently is perhaps more important than replication. (Those of us who have run an errant
deletestatement and wiped out a ton of data, only to see the results replicated immediately already know about the dangers of relying on replication.)