33

你如何通过 PHP 清理 $_GET -variables 中的数据?

我只清理 GET by 中的一个变量strip_tags。我不确定是否应该对所有内容进行清理,因为上次将数据放入 Postgres 时,使用pg_prepare.

4

5 回答 5

86

你如何通过 PHP 清理 $_GET -variables 中的数据?

不会清理 $_GET 中的数据。这是 PHP 脚本中的常用方法,但它是完全错误的*。

您的所有变量都应保持纯文本形式,直到您将它们嵌入另一种类型的字符串中。没有一种形式的转义或“清理”可以涵盖您可能将值嵌入其中的所有可能类型的字符串。

因此,如果您将字符串嵌入到 SQL 查询中,则需要在退出时对其进行转义:

$sql= "SELECT * FROM accounts WHERE username='".pg_escape_string($_GET['username'])."'";

如果您将字符串吐出到 HTML 中,则需要将其转义:

Cannot log in as <?php echo(htmlspecialchars($_GET['username'], ENT_QUOTES)) ?>.

如果您按照不知道自己在做什么的人的建议,在一开始就对 $_GET 数组执行了这两个转义步骤:

$_GET['username']= htmlspecialchars(pg_escape_string($_GET['username']));

然后当你有一个'&' 在您的用户名中,它会神秘地变成“&amp;” 在您的数据库中,如果您的用户名中有一个撇号,它将在页面上变成两个撇号。然后,当您有一个包含这些字符的表单时,很容易在编辑它们时出现双重转义,这就是为什么这么多糟糕的 PHP CMS 最终会出现像“O\\\\的新书”这样的破碎文章标题\\\\\\\\\\\\\\\'赖利”。

自然,每次发送变量时都要记住 pg_escape_string 或 mysql_real_escape_string 和 htmlspecialchars 有点乏味,这就是为什么每个人都想在脚本开头的一个地方(错误地)这样做。对于 HTML 输出,您至少可以通过定义一个具有 echo(htmlspecialchars(...)) 的短名称的函数来节省一些输入。

对于 SQL,最好使用参数化查询。对于 Postgres,有pg_query_params。或者实际上,正如您提到的那样准备好的陈述(尽管我个人认为它们不太容易管理)。无论哪种方式,您都可以忘记“清理”或转义 SQL,但如果您嵌入其他类型的字符串(包括 HTML),您仍然必须转义。

strip_tags() 不是处理 HTML 显示输入的好方法。过去它存在安全问题,因为浏览器解析器在解释标签的含义时实际上比您想象的要复杂得多。htmlspecialchars() 几乎总是使用正确的东西,所以如果有人输入小于号,他们实际上会得到一个字面的小于号,并且不会发现一半的文本神秘地消失了。

(*:无论如何,作为解决注入问题的一般方法。当然,值得对特定字段进行特定于域的检查,并且您可以执行有用的清理任务,例如从提交的值中删除所有控制字符。但这是不是大多数 PHP 编码人员所说的清理。)

于 2009-08-22T11:21:07.423 回答
5

如果您正在谈论清理输出,我建议您将内容以完整的、未转义的形式存储在数据库中,然后在回显数据时对其进行转义(htmlspecialchars或其他内容),这样您就有更多的输出选项。有关清理/转义数据库内容的讨论,请参阅此问题。

在 postgres 中存储方面,在查询中的每个变量上使用pg_escape_string来转义引号,并且通常可以防止 SQL 注入。

编辑:

我在数据库中存储数据然后检索它的通常步骤是:

  1. 调用数据库数据转义函数(pg_escape_string、mysql_escape_string 等)来转义查询中使用的每个传入 $_GET 变量。请注意,当存储在数据库中时,使用这些函数而不是添加斜杠会导致文本中没有额外的斜杠。

  2. 当您从数据库中取回数据时,您可以在任何输出数据上使用 htmlspecialchars,无需使用 stripslashes,因为不应该有额外的斜杠。

于 2009-08-21T22:53:11.603 回答
4

您必须清理所有请求,而不仅仅是 POST 作为 GET。

您可以使用函数htmlentities()preg_replace()带有正则表达式的函数,或按强制转换过滤:

<?
$id = (int)$_GET['id'];
?>
于 2009-08-21T23:07:59.233 回答
2

根据输入的去向对输入进行消毒。

  • 如果您显示它(在页面上或作为输入字段的值),请使用htmlspecialchars和/或str_replace.
  • 如果您将其用作另一种类型,请转换它。
  • 如果您将它包含在 SQL 查询中,请使用适当的函数对其进行转义,如果您确实希望将其完全删除(这与转义不同),则可以剥离 html 标签。

POST 甚至数据库中的数据也是如此,因为数据库中的数据通常不应该被转义。

你应该检查两件事:

  1. 输入与 PHP 脚本/输出/数据库表的编码
  2. 如果已[magic_quotes_gpc][1]启用,则应禁用它(只要可以)或stripslashes()GET、POST 和 COOKIE 值。magic_quotes_gpc已弃用,您应该根据数据的使用情况对您操作的数据进行清理。
于 2009-08-21T23:34:45.467 回答
2

filter_var()使用带有FILTER_SANITIZE_STRING过滤器的 PHP 原生函数。

示例:https ://www.w3schools.com/php/filter_sanitize_string.asp

于 2020-03-01T14:58:14.730 回答