Martin, I've run into this, and my solution for MSSQL was to use Java PreparedStatements). It ties the data to a particular field, so you can pass in whatever you'd like, extra quotes, slashes, escape characters, and it doesn't make a difference. I actually pass that into a stored procedure, but that's more of just a good programming practice in an enterprise environment (IMHO). I'm not sure what other languages have something like a PreparedStatement, but I think it would be a big help to ending this SQL Injection thing. As soon as you can say: $x = new PreparedStatement("select * from table where username = ?"); $x->setString(1, $_GET['username']); then I don't see where the SQL Injection can come into play. Bad data, sure, but you can't jump out of the '?' area. Michael Scovetta -----Original Message----- From: Martin Sarsale (runa@sytes) [mailto:runa@runa.sytes.net] Sent: Thursday, December 04, 2003 2:39 PM To: bugtraq@securityfocus.com Subject: Intresting case of SQL Injection Yesterday, we found an interesting case of SQL Injection. The application was developed under PHP 4.2.1, Apache and MSSQL. We started our tests by adding a ' (single quote) to the POST info. Since PHP escapes ' and " , turning the ' into a \' but SQL Server uses 2 single quotes ('') to escape a quote (') we were allowed to execute our code: select * from users where username='\'; sql code to execute here;-- Then, we wanted to insert a record on the "users" table (fields username and password, both varchar). We found that the application used md5 to store the user passwords but there was a problem: since PHP was auto escaping quotes, we couldn't set the md5 password as a string because sending: insert into users values ('username','password'); would be escaped into insert into users values (\'username\',\'password\'); resulting in a sql error. So, we had to figure out how to insert the username and password as numeric values. Since both fields are varchar, when inserting a number SQL server will cast the number into a string. This is: inserting 123 (numeric) into a varchar field is the same as inserting '123' (string). The username part is easy, we could insert '12345' as the username (any number will work here), but we found a problem with the password: We need a known string which it's md5 hash is ALL NUMERIC. Then, we coded a simple PHP script and found that md5(1518375) = 93240121540327474319550261818423 After that, we sent to the app: '; insert into users (username,password) values (12345,93240121540327474319550261818423);-- which escaped became into: \'; insert into users (username,password) values (12345,93240121540327474319550261818423);-- (valid SQL) Finally, we logged into the webapp using '12345' as username and '1518375' as password. The main problem here was that developers where trusting in PHP auto escaping which worked in MySQL (and probably PostgreSQL) but not in MSSQL. Alejandro Pomeraniec (apomeraniec at buenosaires.gov.ar) Martin Sarsale (msarsale at buenosaires.gov.ar)