通过 PHP 在 GET 中清理用户数据

2022-08-30 13:32:58

如何通过 PHP 清理 $_GET 变量中的数据?

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


答案 1

如何通过 PHP 清理 $_GET 变量中的数据?

不会以 _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']));

然后,当您的用户名中有一个“&”时,它会在您的数据库中神秘地变成“&”,如果您的用户名中有一个撇号,它将在页面上变成两个撇号。然后,当您有一个包含这些字符的表单时,在编辑它们时很容易最终对事物进行双重转义,这就是为什么这么多糟糕的PHP CMS最终会损坏文章标题,例如“来自O\'Reilly的新书”。

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

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

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

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


答案 2

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

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

编辑:

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

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

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


推荐