views:

172

answers:

6

I have tried and tried to achieve an SQL injection by making custom queries to the server outside of firefox.

Inside the php, all variables are passed into the query in a string like this.

Note, by this stage, $_POST has not been touched.

mysql_query('INSERT INTO users (password, username) VALUES(' . sha1($_POST['password']) . ',' . $_POST['username'] . '));

Is that a secure way to make a change?

+3  A: 

You should definitely escape the username with mysql_real_escape_string.

Of course the best solution would be to use prepared statements. That way the separation of query syntax and data is made on the mysql API level.

And, as others pointed out, values should absolutely be surrounded with quotes. Especially the text ones.

macbirdie
Any explanation on the -1? Is there something wrong I wrote?
macbirdie
@macbirdie i didn't give you the -1 but even if he did run $_POST['username'] though addslashes or msyql_real_escape_string it would still be vulnerable because the variable isn't in quotes.
Rook
+2  A: 

Look at http://php.net/mysqli.real-escape-string, adding that to all incomming values should help making it safer.

ba
+3  A: 

what you are doing there is dangerous since someone can send a POST request with an evil user name. you can either check every parameter and escape it, additionally you could use mysqli (http://php.net/manual/en/book.mysqli.php), and bind the parameters using prepare+bind.

the first step is good to avoid exploits on other users, while the second is good for your server side safety.

also check out this question: http://stackoverflow.com/questions/47087/how-do-you-prevent-sql-injection-in-lamp-applications

Yonatan Karni
why is it that I can't explot it then? I've tried countless attempts of common injections and none produce anything...
Supernovah
not sure how your PHP is configured, did you try to print the strings? it may already perform some magic on them. if they don't seem like the strings you sent, you may also want to make sure you are sending them properly, they may be encoded this way or another on the client side.
Yonatan Karni
@Supernovah `$_POST['username']="(select Password from mysql.user limit 1)"` quote marks are not required to exploit this sql injection vulnerability
Rook
I wouldn't like to supply too many examples, but of course you should also be cautious of html/javascript injection.
Yonatan Karni
+1  A: 

this is insecure, unless magic_quotes_gpc configuration directive is turned on.
var_dump(ini_get('magic_quotes_gpc')); or phpinfo(); can show you the actual value

Note that this directive is dirty, deprecated and all-hated. And will make some passwords not work.

Col. Shrapnel
-1 magic_quotes_gpc is very insecure and is being removed in PHP6. Most importantly **this is still SQL Injection even with magic_quotes_gpc** `$_POST['username']` isn't surrounded by quote marks in the query so you could inject something like `(select Password from mysql.user limit 1)`, quote marks are not required for exploitation of this query.
Rook
Ahaha @The lamer trying to lecture me again. Just as with MD5, you just run yelling hysterically "very insecure! very insecure!" But in fact you cannot prove no "very" nor even "insecure" with an example you fool. So, do not say what you just heard but never understand. And nobody asked your opinion on surrounding quotes, because they ARE used in the example. Of course it won't work without quotes. That's obvious
Col. Shrapnel
Wow, if you don't see this specific sql injection vulnerability after I have pointed it out then you have bigger problems than just me.
Rook
forget `magic_quotes`, it does not add even a little bit of security …
knittl
@knittl it does stop *some* SQL Injection and LFI/RFI attacks, but agree that by in large its hazardous becuase the programmer should be more aware of the filters that he is putting in place. A very good example is this sql injection vuln that isn't obvious to everyone, but if you used parametrized queries it wouldn't be an issue.
Rook
+2  A: 

On checking your code I'm surprised it works at all when you don't quote the literals you are inserting - you will be generating code like:

INSERT INTO user (password, username) VALUES (abc1234fg00000, admin);

So it will give an error every time. Assuming this is just a typo....

The mysql extension limits your ability to perform injection attacks by only allowing one query per call. Also, there is limited scope for an injection attack on a INSERT statement. Add to that the fact that you change the representation to a neutral format before splicing into the insert statement means that it is not a potential avenue for such an attack. However, your code should fall over if someone POSTs a username containing a single quote (if it doesn't then you've got magic_quotes enabled enabled which is deprecated).

OTOH if you apply the same method to validating the account then you are wide open to injection attacks - consider

"SELECT 1 
FROM users
WHERE username='" . $_POST['username'] . "'
AND password='" . sha1($_POST['username'] . "';";

If $_POST['username'] contains "admin' OR 1 " then your system is compromised.

You should always use mysql_real_escape_string() unless you've made the data safe using a different function (e.g. sha1, bas64_encode....but NOT addslashes)

C.

symcbean
good point on wrong query syntax
Col. Shrapnel
I can't agree with `sha1, bas64_encode` stuff. all these things has nothing to do with database. you can change your mind and quit use these functions. but query building algorithm should be the same. Better to make it abstract, and independent from data value.
Col. Shrapnel
@Col. Shrapnel: but sha1($x)===mysql_real_escape_string(sha1($x)) and base64_encode($x)===mysql_real_escape_string(base64_encode($x)) regardless of what $x is. Note I'm not saying that you should NOT use mysql_real_escape_string() just that it is redundant in some cases.
symcbean
No, it is not redundant. Actually I've answered to your comment before, but I'll repeat: Query builder should know nothing of the data. Parametrized queries is a good example: they never ask you if you think it's redundant or not to prepare data. You just do it obligatory. That's the only parametrized queries benefit over traditional way. And good example to follow
Col. Shrapnel
A: 

I wonder sometimes if they'll find me in the old folks home, screaming "BIND VARIABLES" at the nurses as they walk by.

It's 2010 people, not 1995.

BIND VARIABLES!

BIND VARIABLES!

Jason