通过 PHP 清理 GET 中的用户数据
如何通过 PHP 清理 $_GET 变量中的数据?
我仅通过 strip_tags
清理 GET 中的一个变量。
我不确定是否应该清理所有内容,因为上次将数据放入 Postgres 时,使用 pg_prepare 最容易解决问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您不清理$_GET 中的数据。这是 PHP 脚本中的常见方法,但它是完全错误的*。
所有变量都应保持纯文本形式,直到将它们嵌入另一种类型的字符串中为止。没有一种形式的转义或“清理”可以涵盖您可能嵌入值的所有可能类型的字符串。
因此,如果您将字符串嵌入到 SQL 查询中,则需要在退出时对其进行转义:
如果您要将字符串吐出到 HTML 中,则需要对其进行转义:
如果您执行了这两个转义步骤在开头的 $_GET 数组上,正如那些不知道自己在做什么的人所建议的那样:
然后当你有一个 '&'在你的用户名中,它会神秘地变成“&”在您的数据库中,如果您的用户名中有撇号,它会在页面上变成两个撇号。然后,当您的表单中包含这些字符时,在编辑它们时很容易出现双重转义,这就是为什么许多糟糕的 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 程序员所说的清理的意思。)
You do not sanitize data in $_GET. This is a common approach in PHP scripts, but it's completely wrong*.
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:
And if you're spitting the string out into HTML, you need to escape it then:
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:
Then when you had a ‘&’ in your username, it would mysteriously turn into ‘&’ 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”.
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(...)).
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.
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.
(*: 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.)
如果您正在谈论清理输出,我建议将内容以完整的、未转义的形式存储在数据库中,然后转义它(htmlspecialchars 或其他)当您回显数据时,这样您就有更多的输出选项。请参阅此问题进行讨论清理/转义数据库内容。
在postgres中存储方面,使用 pg_escape_string查询中的每个变量,以转义引号,并通常防止 SQL 注入。
编辑:
我在数据库中存储数据然后检索数据的通常步骤是:
调用数据库数据转义函数(pg_escape_string、mysql_escape_string 等),以转义查询中使用的每个传入 $_GET 变量。请注意,使用这些函数而不是addslashes 会导致文本存储在数据库中时不会有多余的斜杠。
当你从数据库中取回数据时,你可以在任何输出的数据上使用 htmlspecialchars,不需要使用 stripslashes,因为不应该有额外的斜杠。
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 (htmlspecialchars or something) when you are echoing out the data, that way you have more options for outputting. See this question for a discussion of sanitising/escaping database content.
In terms of storing in postgres, use pg_escape_string on each variable in the query, to escape quotes, and generally protect against SQL injection.
Edit:
My usual steps for storing data in a database, and then retrieving it, are:
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.
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.
您必须清理所有请求,而不仅仅是 POST 作为 GET。
您可以使用函数htmlentities(),函数
preg_replace()
使用正则表达式,或通过强制转换进行过滤:You must sanitize all requests, not only POST as GET.
You can use the function htmlentities(), the function
preg_replace()
with regex, or filter by cast:根据输入的去向对其进行清理。
htmlspecialchars
和/或str_replace
。对于 POST 甚至数据库中的数据也是如此,因为数据库中的数据通常不应被转义。
您应该检查两件事:
[magic_quotes_gpc][1]
,您应该禁用它(只要可以)或 < code>stripslashes() GET、POST 和 COOKIE 值。magic_quotes_gpc
已弃用,您应该根据该数据的使用来清理您操作的数据。Sanitize your inputs according to where it is going.
htmlspecialchars
and/orstr_replace
.Same for POST or even data from your DB, since the data inside your DB should generally not be escaped.
Two things you should check:
[magic_quotes_gpc][1]
enabled, you should either disable it (whenever you can) orstripslashes()
GET, POST and COOKIE values.magic_quotes_gpc
is deprecated, you should sanitize the data you manipulate, depending on the use of that data.将 PHP 本机函数
filter_var()
与FILTER_SANITIZE_STRING
过滤器结合使用。示例: https://www.w3schools.com/php/filter_sanitize_string.asp
Use a PHP native function
filter_var()
withFILTER_SANITIZE_STRING
filter.Example: https://www.w3schools.com/php/filter_sanitize_string.asp