【问题标题】:mysqli_real_escape_string - example for 100% safetymysqli_real_escape_string - 100% 安全示例
【发布时间】: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


【解决方案1】:

您的孤立和简化示例在技术上是安全的。

但是,它仍然存在两个问题:

  • 假设:问题的陈述是基于mysqli_real_escape_string() 与任何安全问题相关的假设。这只是一个严重的错觉。这是一个字符串格式化函数,仅作为副作用保护您免受 SQL 注入。但这样的保护既不是功能的目标也不是目的。因此,绝不应将其用于此目的。
  • 您提交的代码固有的可分离性。保护由三个部分组成:
    • 设置正确的编码
    • 转义特殊字符
    • 将转义值用引号括起来

这不仅是其中一些强制性措施could be forgotten 的事实,而且问题的陈述仅强调一个部分 - 转义。总是强调的只是逃避,而其他两项措施则几乎没有提及。看看你的问题——你的意思是代码,但问的是函数。因此,对您提出的问题的任何字面回答都会给人一种致命的错误印象,即mysqli_real_escape_string() 没问题。

简而言之,问题陈述有助于促进与 PHP 相关的最危险的妄想:该函数可防止 SQL 注入。

与这个复杂的三部分方程式不同,准备好的陈述构成了一个不可分割的度量。你不能忘记一个部分。你不能滥用它。尝试mysqli_real_escape_string() 保护标识符,它会默默地被忽视,直到实际注入发生。为标识符尝试一个准备好的语句 - 并得到一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-09
    • 2016-11-10
    • 2014-04-24
    • 2012-04-12
    • 2023-04-05
    • 2015-10-31
    • 1970-01-01
    相关资源
    最近更新 更多