【发布时间】:2016-03-07 06:14:41
【问题描述】:
我知道已经有很多关于这个话题的问题被问到。而且我也知道要走的路是准备好的陈述。但是,我仍然没有完全理解以下是否或如何成为安全问题:
$mysqli = new mysqli("localhost", "root", "", "myDatabase");
$mysqli->set_charset("utf8");
$pw = mysqli_real_escape_string($mysqli,$_POST['pw']);
$username = mysqli_real_escape_string($mysqli,$_POST['username']);
$str = "SELECT * FROM users WHERE id='".$id."' AND username='".$username."'";
$result = $this -> mysqli -> query($qstr);
if($result->num_rows > 0){
//user logged in
}
我从注入备忘单尝试了许多不同的输入,但找不到任何通过查询的内容。例如。如果我输入任何带有“;”的内容然后 $result 变为错误,因为据我所知,一个查询不能包含两个单独的语句。任何带有 ' 或 " 的输入都由 mysqli_real_escape_string。
能否请您解释一下,上面的代码是如何被利用的?如果你有一个链接,它解释了它,我也很乐意阅读它!
干杯
编辑:这个答案已经回答了:
SQL injection that gets around mysql_real_escape_string()
然而,这个问题是关于旧版本的 mysql 而不是 mysqli。其次,投票最多的答案说明了以下可以绕过它的示例:
mysql_query('SET NAMES gbk');
$var = mysql_real_escape_string("\xbf\x27 OR 1=1 /*");
mysql_query("SELECT * FROM test WHERE name = '$var' LIMIT 1");
但是我并不完全理解这一点。第一行
mysql_query('SET NAMES gbk');
不能从外部设置,对吗?如果有人在他的程序中设置了“gbk”,这只是一个示例。所以如果我用了
$mysqli->set_charset("utf8");
也用过
id='".$id."' (single quotes around $id)
那么我会 100% 安全,对吗?
【问题讨论】:
-
是的,这通常是安全的。正确使用时,Mysql 和 mysqli 是完全安全的(尽管在非常特定的编码中存在特定的错误)。准备好的语句的优点是更难以错误的方式做事。
-
好的,知道了!非常感谢!
-
是的,有些情况下转义字符串不起作用,但它们是模糊的边缘情况。但是考虑到编写带有查询参数的代码工作量更少,并且代码更容易阅读和更容易维护,解决方案查询参数应该是首选。
标签: php mysqli sql-injection