准备好的 SQL 语句与 htmlspecialchars 转换的 GET 变量有何不同?
In what does prepared SQL statement differ from htmlspecialchars converted GET variable?
所以我在我的网站上搞乱了 SQL 注入,试图找到一种简单的方法来保护它免受 SQL 注入。我发现了很多关于 "Prepared SQL statements" 的东西,主要是在 this post.
这很好,是的,它确实防止了我所知道的任何类型的 SQL 注入,并且还防止了所有用于测试安全性的应用程序 SQL 注入。
但是,我发现所有注入都是一样的,那就是使用 ' 引号。我的问题是:为什么要使用准备好的语句或类似的东西,当我可以简单地阻止查询 运行 使用 htmlspecialchars?
示例:
$id = htmlspecialchars($_GET['id'], ENT_QUOTES);
$query = Mysqli_Query($dbc, "SELECT * FROM `Users` WHERE `user_id`='$id'") or die(mysql_error());
这通过将 ' 字符更改为 ' 来防止所有注入,这在 MYSQL 语句中是无效的。
我是不是漏掉了什么?为什么人们改用准备好的语句是有原因的?
好吧 htmlspecialchars()
以与 str_replace("'",'',$_GET['id'])
相同的方式保护您。他们都以不保留数据的方式更改原始数据 "as is"。更重要的是,由于它们不是这项工作的预期功能,相同的编码、字符集(或其他因素,我不知道)可能会打败 "protection"。如果您不想使用准备好的语句,正确的函数是 mysqli_real_escape_string(或类似的 OOP)(请注意名称上的 "i")也请注意,即使是此函数也需要注意字符集.两个旁注:对于预期的整数,停止注入就足够了:$value = (int)$_GET['id']
,以防止 XSS 注入使用 htmlspecialchars
参数化查询是数据库功能;数据库本身提供了一个 API 来分别获取查询及其数据。这使得出现任何问题的可能性 为零*。将其与您在 PHP 中执行的任何字符串 encoding/slicing/replacing 操作进行比较,最终您仍将向数据库发送一个长字符串。你将不得不考虑每一个。可能的。组合。 可能逃脱(没有双关语意)您的消毒工作的字符。您还必须知道 MySQL 理解的每一种可能的转义序列组合,这可能会导致意想不到的结果。你逃脱了 '
,太好了。我将插入一个 \
作为我的字符串中的最后一个字符怎么样?那么您的查询将是:
INSERT INTO foo VALUES ('bar"\')
糟糕。**
话筒掉落
* 当然你也可以搬起石头砸自己的脚,但至少在逃跑方面,它是可靠的。
** 如果您看不到此查询的问题,请参阅下面的评论。
所以我在我的网站上搞乱了 SQL 注入,试图找到一种简单的方法来保护它免受 SQL 注入。我发现了很多关于 "Prepared SQL statements" 的东西,主要是在 this post.
这很好,是的,它确实防止了我所知道的任何类型的 SQL 注入,并且还防止了所有用于测试安全性的应用程序 SQL 注入。
但是,我发现所有注入都是一样的,那就是使用 ' 引号。我的问题是:为什么要使用准备好的语句或类似的东西,当我可以简单地阻止查询 运行 使用 htmlspecialchars?
示例:
$id = htmlspecialchars($_GET['id'], ENT_QUOTES);
$query = Mysqli_Query($dbc, "SELECT * FROM `Users` WHERE `user_id`='$id'") or die(mysql_error());
这通过将 ' 字符更改为 ' 来防止所有注入,这在 MYSQL 语句中是无效的。
我是不是漏掉了什么?为什么人们改用准备好的语句是有原因的?
好吧 htmlspecialchars()
以与 str_replace("'",'',$_GET['id'])
相同的方式保护您。他们都以不保留数据的方式更改原始数据 "as is"。更重要的是,由于它们不是这项工作的预期功能,相同的编码、字符集(或其他因素,我不知道)可能会打败 "protection"。如果您不想使用准备好的语句,正确的函数是 mysqli_real_escape_string(或类似的 OOP)(请注意名称上的 "i")也请注意,即使是此函数也需要注意字符集.两个旁注:对于预期的整数,停止注入就足够了:$value = (int)$_GET['id']
,以防止 XSS 注入使用 htmlspecialchars
参数化查询是数据库功能;数据库本身提供了一个 API 来分别获取查询及其数据。这使得出现任何问题的可能性 为零*。将其与您在 PHP 中执行的任何字符串 encoding/slicing/replacing 操作进行比较,最终您仍将向数据库发送一个长字符串。你将不得不考虑每一个。可能的。组合。 可能逃脱(没有双关语意)您的消毒工作的字符。您还必须知道 MySQL 理解的每一种可能的转义序列组合,这可能会导致意想不到的结果。你逃脱了 '
,太好了。我将插入一个 \
作为我的字符串中的最后一个字符怎么样?那么您的查询将是:
INSERT INTO foo VALUES ('bar"\')
糟糕。**
话筒掉落
* 当然你也可以搬起石头砸自己的脚,但至少在逃跑方面,它是可靠的。
** 如果您看不到此查询的问题,请参阅下面的评论。