views:

310

answers:

7

Does the following PHP MySQL statement protect against SQL Injection?

$strSQL = "SELECT * FROM Benutzer WHERE Benutzername = '".$Benutzer."' AND Password = '".md5($PW)."'";

The Variables $Benutzer and $PW are inputs from the User.

We're checking the username and password against common SQL Injection techniques:

' or 0=0 --, " or 0=0 --, or 0=0 --, ' or 0=0 #, " or 0=0 #, or 0=0 #, ' or 'x'='x, " or "x"="x, ') or ('x'='x, ' or 1=1--, " or 1=1--, or 1=1--, ' or a=a--, " or "a"="a, ') or ('a'='a, ") or ("a"="a, hi" or "a"="a, hi" or 1=1 --, hi' or 1=1 --, hi' or 'a'='a, hi') or ('a'='a and hi") or ("a"="a.

Am I missing something? Should I use a different method to protect against SQL injection?

A: 

Try using mysql_real_escape_string()

$strSQL = "SELECT * 
  FROM Benutzer 
  WHERE Benutzername = '".mysql_real_escape_string($Benutzer)."' 
  AND Passwort = '".mysql_real_escape_string(md5($PW))."'";

Make sure that when users register, you register using the same technique .. for example,

AND Passwort = '".mysql_real_escape_string(md5($PW))."'"

and

AND Passwort = '".md5(mysql_real_escape_string($PW))."'"

may produce different results depending upon the input text.

And yes, also add some "salt" to this password as well. For some ideas you do like this

sha1(md5($pass)):
sha1($salt.$pass):
sha1($pass.$salt):
sha1($username.$pass):
sha1($username.$pass.$salt):

Wbdvlpr
There is no need to escape the password with `mysql_real_escape_string()`, since MD5s are hexadecimal numbers, and will not contain anything but the characters 0-9 or A-F.
Ryan McCue
No, do not use string escaping. Use bound parameters.
Andrew Medico
There may be no need to escape in that particular case, but it's a good habit to get into to use the escaping on *every* string if you're going to be using string-building. Separation of concerns: it's not the job of your query builder to know what are valid characters in an MD5 digest, and maybe in the future someone will swap the md5 call for something else that can include characters you do need to worry about.
bobince
@bobince - Thanks for standing by me.
Wbdvlpr
+6  A: 

I'd personally advise using an algorithm such as SHA1 over MD5, as there is a lower possibility of collisions. You should be salting your passwords too, otherwise one can use rainbow tables to crack your passwords.

Also, use mysql_real_escape_string() to escape things, don't simply do a search and replace for common injections.

Ryan McCue
No, do *not* use string escaping. String escaping is very easy to do wrong, and hard to do right. Use bound parameters. Bound parameters are sent to the database through alternate channels, and so cannot possibly be parsed as SQL.
Andrew Medico
`mysql_real_escape_string()` is executed by the MySQL server, and I believe the MySQL guys know a thing or two about getting that stuff right.
Ryan McCue
Or, rather, the MySQL library in PHP, which is made by the MySQL team, IIRC.
Ryan McCue
thank you all - we will add a little bit of salt to the password and use the mysql_real_escape_string() to protect the user inputs we used in our sql-statements.
snuffer.ch
@Ryan McCue: you'd hope so, but not really. mysql_real_escape_string() exists because its predecessor mysql_escape_string was horribly broken. And anyway it's still a flawed methodology.
Andrew Medico
MySQL string literal escaping isn't hard to do right, it's just easy to forget to do, which is why parameterised queries are a good thing. But Ryan is correct that escaping is the right concept (whether explicitly or via parameters), whilst trying to sniff for “bad” strings that “might” be signs of an injection attempt is totally the wrong thing: laughably incomplete, whilst also blocking some valid input.
bobince
+3  A: 

If security is supposed to be as high as possible, you ought to use some other hashing method than md5 - like e.g. sha256. Also, use a password salt.

gnud
He is asking about SQL injection.
Pawka
Yes, and that part was already answered. He also said that he wants high security - so I gave him some extra tips, free of charge.
gnud
+9  A: 

You may want to look into parameterized queries for querying the database. This eliminates SQL injection attacks.

I work primarily with postgreSQL, and the format for doing such a query would look something like this:

$query = 'select * from Benutzer where Benutzername = $1 and Passwort = $2';
$params = array($Benutzer, md5($PW));
$results = pg_query_params($query, $params);

Most databases have a function that will be similar to this funationality.

I hope this helps and good luck!

Kyle

Kyle J. Dye
PDO works like this. see http://fr2.php.net/manual/en/pdostatement.execute.php
Aif
+4  A: 

Prepared statements are a fantastic invention.

http://www.php.net/manual/en/pdo.prepare.php and http://www.php.net/manual/en/mysqli.prepare.php for examples.

Björn
A: 

The security standards should be as high as possible.

If md5 got included in your design with nobody raising an eyebrow or spitting coffee on themselves, then you need to revisit the security issue with the client. If security is that critical they need to spring for a security specialist to join your team. Everybody says they want secure code. Few are willing to pay for it, so few actually get it.

quillbreaker
A: 

Be sure to strip_tags any public content (or use your own html filter) to prevent XSS as well.

Citizen
htmlspecialchars() during the output phase is the correct thing to do to prevent XSS.
bobince
Unless you want to display some user generated html...
Citizen