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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1314518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 02:00:13  来源:igfitidea点击:

Sanitizing user's data in GET by PHP

phpgetsanitization

提问by Léo Léopold Hertz ??

How do you sanitize data in $_GET -variables by PHP?

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

I sanitize only one variable in GET by strip_tags. I am not sure whether I should sanitize everything or not, because last time in putting data to Postgres, the problem was most easily solved by the use of pg_prepare.

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

回答by bobince

How do you sanitize data in $_GET -variables by PHP?

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

You do notsanitize data in $_GET. This is a common approach in PHP scripts, but it's completely wrong*.

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

All your variables should stay in plain text form until the point when you embed them in another type of string. There is no one form of escaping or ‘sanitization' that can cover all possible types of string you might be embedding your values into.

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

So if you're embedding a string into an SQL query, you need to escape it on the way out:

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

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

And if you're spitting the string out into HTML, you need to escape it then:

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

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

If you did both of these escaping steps on the $_GET array at the start, as recommended by people who don't know what they're doing:

如果您在开始时对 $_GET 数组执行了这两个转义步骤,正如不知道自己在做什么的人所建议的那样:

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

Then when you had a ‘&' in your username, it would mysteriously turn into ‘&amp;' in your database, and if you had an apostrophe in your username, it would turn into two apostrophes on the page. Then when you have a form with these characters in it is easy to end up double-escaping things when they're edited, which is why so many bad PHP CMSs end up with broken article titles like “New books from O\\\\\\\\\\\\\\\\\\\'Reilly”.

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

Naturally, remembering to pg_escape_string or mysql_real_escape_string, and htmlspecialchars every time you send a variable out is a bit tedious, which is why everyone wants to do it (incorrectly) in one place at the start of the script. For HTML output, you can at least save some typing by defining a function with a short name that does echo(htmlspecialchars(...)).

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

For SQL, you're better off using parameterised queries. For Postgres there's pg_query_params. Or indeed, prepared statements as you mentioned (though I personally find them less managable). Either way, you can then forget about ‘sanitizing' or escaping for SQL, but you must still escape if you embed in other types of string including HTML.

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

strip_tags() is not a good way of treating input for HTML display. In the past it has had security problems, as browser parsers are actually much more complicated in their interpretation of what a tag can be than you might think. htmlspecialchars() is almost always the right thing to use instead, so that if someone types a less-than sign they'll actually get a literal less-than sign and not find half their text mysteriously vanishing.

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

(*: as a general approach to solving injection problems, anyway. Naturally there are domain-specific checks it is worth doing on particular fields, and there are useful cleanup tasks you can do like removing all control characters from submitted values. But this is not what most PHP coders mean by sanitization.)

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

回答by Alistair Evans

If you're talking about sanitizing output, I would recommend storing content in your database in it's full, unescaped form, and then escaping it (htmlspecialcharsor something) when you are echoing out the data, that way you have more options for outputting. See thisquestion for a discussion of sanitising/escaping database content.

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

In terms of storing in postgres, use pg_escape_stringon each variable in the query, to escape quotes, and generally protect against SQL injection.

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

Edit:

编辑:

My usual steps for storing data in a database, and then retrieving it, are:

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

  1. Call the database data escaping function (pg_escape_string, mysql_escape_string, etc), to escape each incoming $_GET variable used in your query. Note that using these functions instead of addslashes results in not having extra slashes in the text when stored in the database.

  2. When you get the data back out of the database, you can just use htmlspecialchars on any outputted data, no need to use stripslashes, since there should be no extra slashes.

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

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

回答by fvox

You must sanitize all requests, not only POST as GET.

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

You can use the function htmlentities(), the function preg_replace() with regex, or filter by cast:

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

<?
$id = (int)$_GET['id'];
?>

[]'s

[] 的

回答by instanceof me

Sanitize your inputs according to where it is going.

根据您的输入进行消毒。

  • If you display it (on a page or as an input field's value), use htmlspecialcharsand/or str_replace.
  • If you use it as another type, cast it.
  • If you include it in SQL query, escape it using the appropriate function, maybe strip html tags if you do want those to be totally removed (which is not the same as escaped).
  • 如果您显示它(在页面上或作为输入字段的值),请使用htmlspecialchars和/或str_replace
  • 如果您将其用作另一种类型,请强制转换。
  • 如果您将它包含在 SQL 查询中,请使用适当的函数对其进行转义,如果您确实希望完全删除 html 标签(这与转义不同),则可以去除 html 标签。

Same for POST or even data from your DB, since the data inside your DB should generally not be escaped.

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

Two things you should check:

你应该检查两件事:

  1. Encoding of your input vs. your PHP scripts / output / DB table
  2. If you have [magic_quotes_gpc][1]enabled, you should either disable it (whenever you can) or stripslashes()GET, POST and COOKIE values. magic_quotes_gpcis deprecated, you should sanitize the data you manipulate, depending on the useof that data.
  1. 输入与 PHP 脚本/输出/数据库表的编码
  2. 如果已[magic_quotes_gpc][1]启用,则应禁用它(只要可以)或stripslashes()GET、POST 和 COOKIE 值。magic_quotes_gpc已弃用,您应该清理您操作的数据,具体取决于该数据的使用

回答by Jitu

Use a PHP native function filter_var()with FILTER_SANITIZE_STRINGfilter.

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

Example: https://www.w3schools.com/php/filter_sanitize_string.asp

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