可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This question already has answers here:
Closed 7 years ago.
Possible Duplicate:
What does mysql_real_escape_string() do that addslashes() doesn't?
I have been reviewing articles on how/why PHP's addslashes function is vulnerable to sql injection. Everything I have read says there are problems with specific mysql encoding types (default-character-set=GBK), or there are problems if magic_quotes are enabled. However, I have been unable break out of the addslashes() function in this scenario and do something malicious - such as login as an administrator.
$user = addslashes($_POST['user']);
$pass = sha1($_POST['pass']);
$sql = "SELECT * FROM admins WHERE user = '".$user."' AND `pass` = '".$pass."'";
$nums = mysql_num_rows(mysql_query($sql));
if($nums==1){
$_SESSION['admin_user'] = $user;
$_SESSION['admin_pass'] = $pass;
This is a (minor) security audit for a client and I will recommend that they utilize PDO, but I need to display their current vulnerability.
References:
- http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string
- http://hakipedia.com/index.php/SQL_Injection#addslashes.28.29_.26_magic_quotes_gpc
回答1:
Shiflett shows a full working exploit in his blog entry. The code you show above doesn't seem to be following that example as it's not using the character set that exhibits the vulnerability. Still, the hole definitely exists.
Even if it happens to be safe in the specific scenario, the practice of using addslashes()
is still dangerous and Shiflett's article should give you enough material to argue with, even though the circumstances the exploit requires are very esoteric, and they're not entirely trivial to reproduce.
If your client doesn't accept the danger without seeing a live exploit on their specific system, then they're not worth doing a security audit for.
回答2:
Is PHP's addslashes vulnerable to sql injection attack?
Yes.
With the conditions mentioned in the article you linked to.
I need to display their current vulnerability.
I doubt you can display this one, as it seems the client's encoding is not the renowned GBK.
Though, there most likely exists other possible vulnerabilities, just because people tend to misuse an escaping function, taking it wrong.
But I can assure you that as long as your client's encoding either single-byte one or UTF-8, and as long as this function used properly (as in the code you posted)- there would be no injection possible.
回答3:
For your particular case, it does not seem that it is as easy to perform SQL injection, but a common thing to try is something like, if i enter a unicode null variable? like \0
? Will it break the script and return everything? Most likely not.
So thing is, you do not always need slashes to perform SQL injection. Some SQL can be written so horrible wrong, heres an example
"SELECT * FROM admins WHERE id = $id"
If $id
is a number, its perfectly valid SQL, and you perform addslashes
on $id, (who would do that anyway?). But for this specific case, all you need for SQL injection is 1 OR 1=1
making the query look like
"SELECT * FROM admins WHERE id = 1 OR 1=1"
There is no way addslashes
or magic_quotes
could protect you against that sort of stupidity.
To get back to the question at hand, why would anyone in their right mind ever use GBK
over something like UTF-8
or UTF-16
?
回答4:
I'm not sure why you would want to use addslashes over mysql_real_escape_string() but that's entirely your choice I suppose.
addslashes() does exactly what it says: Quote string with slashes
Example #1 An addslashes() example
<?php
$str = "Is your name O'reilly?";
// Outputs: Is your name O\'reilly?
echo addslashes($str);
But some SQL attacks can be performed without quotes (certain shell injections and some blind SQL injections).
For this reason I would personally use mysql_real_escape_string() over addslashes() for securing your data in THIS case.
Also consider using sprintf() for your sql queries as it makes it slightly more secure:
$query = sprintf("SELECT `username`,`password`
FROM admins
WHERE user = '%s'
AND `pass` = '%s'",
$user, $pass);
It makes it more secure as it won't allow any other data-types than the ones that you have given.
%d = digit
%s = string,
etc.
I hope this helps.