2

我读过这已经足够了,甚至建议在输出上转义字符,而不是在输入上。

它可以很容易地应用于所有 get 变量,因为它们不会从表单级别注入数据库。

但是,我不确定如何处理所有帖子变量。如果它不是来自数据库,那么如果它是原始输入数据,则完全需要转义。但我正在使用 PDO 准备/执行来转义所有变量。现在的问题:

  1. 在 select 和 insert 语句中都使用 PDO 的准备/执行是否可以?不是两次转义变量吗?
  2. 假设我通过 PDO exeute 语句得到了一些变量 - 是否可以简单地使用 $_POST['variable'] 显示这个变量而不转义它(如果它已经在 PDO 函数中完成)?
  3. htmlspecialchars() 是否足以逃避诸如 GET 变量之类的不是来自数据库的东西?

最重要的是——所有这些、PDO 准备/执行和 htmlspecialchars() 是否足以阻止所有 XSS 攻击?还是我也应该做更多?如果是这样,这应该是什么?从输入中删除所有 html 标签?改用 BB 码?

4

4 回答 4

9

我读过这已经足够了,甚至建议在输出上转义字符,而不是在输入上。

通常,您希望:

  • 使用准备好的语句验证输入并存储它。准备好的语句将保护您的数据库免受 SQL 注入。通常,您不希望在输入时去除 HTML 标记,因为这样做可能会导致数据完整性丢失。
  • 在显示用户生成的数据(输出)时,您可以结合使用 htmlentities 和 mb_convert_encoding 来防范 XSS。

注意另一个问题的htmlspecialchars函数:

即使您在 HTML 标记之外使用 htmlspecialchars($string),您仍然容易受到多字节字符集攻击向量的攻击。

最有效的方法是使用 mb_convert_encodinghtmlentities的组合,如下所示。

$str = mb_convert_encoding($str, ‘UTF-8′, ‘UTF-8′);
$str = htmlentities($str, ENT_QUOTES, ‘UTF-8′);
于 2012-11-02T16:23:33.020 回答
2

在输出上转义字符,而不是在输入上

是的。

轻松应用于所有获取变量

但是 $_GET 是根据定义 输入

不是两次转义变量吗?

不 - 通过转义内容,您只是将其与处理代理的错误解释隔离开来。数据库不存储转义数据,它存储原始数据。

因此,如果从

O'Reilly

然后转义将其拼接成一个SQL字符串......

O\'Reilly

然后存储在数据库中并由 SELECT 语句检索的值是

O'Reilly

当你想输出你的 HTML 时,你可以通过 htmlspecialchars() 来获取

O"Reilly

您可以根据数据的去向使用适当的方法来转义数据 - 因此在将内容放入数据库时​​使用 mysql_real_escape() 或参数绑定或类似方法,在将内容放入html 时使用 htmlspecialchars ( )

于 2012-11-02T16:26:40.010 回答
1
  1. 每当数据来自用户时,对其进行清理(如果将其存储在数据库中,请特别注意。)。所以带有prepared statement的PDO是必须的。你做的其他事情就是额外的奖金。

  2. 是的(这里的观点因人而异)用于防止 sql 注入(假设您使用的是准备好的语句)。虽然我更喜欢将原始数据存储在数据库中,即使这意味着牺牲一些恶意 XSS 代码可能包含它。输出时,请格外小心。

  3. 不,使用htmlpurifier(使用您从数据库输出的视图。)

于 2012-11-02T16:21:56.077 回答
0

我使用 mysqli_real_escape_string 和 preg_replace

$email = mysqli_real_escape_string($dbc, trim($_POST['email']));
$password = mysqli_real_escape_string($dbc, trim($_POST['password']));
$domain = preg_replace('/^[a-zA-Z0-9][a-zA-Z0-9\._\-&!?=#]*@/', '', $email);

此外,这里是一个类似帖子的链接,关于 PDO 转义PDO 语句的 Escape 参数?

于 2012-11-02T16:20:16.400 回答