【问题标题】:Sanitizing PHP/SQL $_POST, $_GET, etc...?清理 PHP/SQL $_POST、$_GET 等...?
【发布时间】:2012-01-14 07:49:23
【问题描述】:

好的,这个主题是我理解的温床。我也了解这种情况取决于您使用的代码。我有三种情况需要解决。

  1. 我有一个表格,我们需要在该表格中允许人们使用逗号、波浪线等来制作 cmets 和语句......但仍然可以免受攻击。

  2. 我有人输入这样的日期:10/13/11 mm/dd/yy 英文,这可以消毒吗?

  3. 我如何理解如何正确使用htmlspecialchars()htmlentities()real_escape_string()?我已经阅读了 php.net 网站和这里的一些帖子,但在我看来,这完全取决于阅读问题的人正确答案是什么。

我真的不能接受...必须有一个答案,其中类似于我在这里发布的文本格式可以被清理。我想知道它是否以及如何可能。

谢谢...因为在我看来,当在其他地方问这个问题时,它往往会惹恼...我正在学习我需要知道的东西,但我认为我已经达到了没有它是做什么的例子......

提前致谢。

【问题讨论】:

  • 令人惊讶的是,您最终在 Web 应用程序中的字符串清理上花费了多少时间。我敢说,我编写的绝大多数 PHP 代码都是纯字符串操作。相比之下,实际的“逻辑”部分就显得苍白无力。

标签: php mysql-real-escape-string html-entities htmlspecialchars


【解决方案1】:

这是一个非常重要的问题,它实际上以编码的形式给出了一个简单的答案。您面临的问题是您同时使用多种语言。首先是 HTML,然后是 PHP,几秒钟后是 SQL。所有这些语言都有自己的语法规则。

要记住的是:字符串应始终采用正确的编码。

让我们举个例子。您有一个 HTML 表单,用户在其中输入以下字符串:

I really <3 dogs & cats ;')

按下提交按钮后,此字符串将发送到您的 PHP 脚本。让我们假设这是通过 GET 完成的。它被附加到具有自己的语法(例如 & 字符具有特殊含义)的 URL 上,因此我们正在更改语言。这意味着必须将字符串转换为正确的 URL 编码。在这种情况下,浏览器会执行此操作,但 PHP 也有一个 urlencode 函数。

在 PHP 脚本中,字符串存储在 $_GET 中,编码为 PHP 字符串。只要您正在编写 PHP 代码,这完全没问题。但现在让我们将字符串用于 SQL 查询。我们更改语言和语法规则,因此必须通过mysql_real_escape_string 函数将字符串编码为SQL。

在另一端,我们可能希望再次将字符串显示给用户。我们从数据库中检索字符串,并将其作为 PHP 字符串返回给我们。当我们想将它嵌入到 HTML 中进行输出时,我们再次更改了语言,因此我们必须通过 htmlspecialchars 函数将我们的字符串编码为 HTML。

在整个过程中,字符串始终采用正确的编码,这意味着用户可以想出的任何字符都会得到相应的处理。一切都应该运行顺利且安全。

要避免的事情(有时甚至被无知者推荐)是过早地编码您的字符串。例如,您可以将htmlspecialchars 应用于字符串之前 将其放入数据库。这样,当您稍后从数据库中检索字符串时,您可以将其粘贴到 HTML 中,这没有问题。听起来不错?是的,真的很棒,直到您开始收到人们的支持票,他们想知道为什么他们的 PDF 收据中充满了& > 垃圾。

在代码中:

form.html:

<form action="post.php" method="get">
    <textarea name="comment">
        I really <3 dogs &amp; cats ;')
    </textarea>
    <input type="submit"/>
</form>

它生成的网址:

http://www.example.org/form.php?comment=I%20really%20%3C3%20dogs%20&amp;%20cats%20;')

post.php:

// Connect to database, etc....

// Place the new comment in the database
$comment = $_GET['comment']; // Comment is encoded as PHP string

// Using $comment in a SQL query, need to encode the string to SQL first!
$query = "INSERT INTO posts SET comment='". mysql_real_escape_string($comment) ."'";
mysql_query($query);

// Get list of comments from the database
$query = "SELECT comment FROM posts";

print '<html><body><h2>Posts</h2>';
print '<table>';

while($post = mysql_fetch_assoc($query)) {
    // Going from PHP string to HTML, need to encode!
    print '<tr><td>'. htmlspecialchars($post['comment']) .'</td></tr>';
}

print '</table>';
print '</body></html>'

【讨论】:

  • +1 用于提及为什么在插入数据库之前进行 HTML 编码是一个坏主意。
  • 你能说明你在说什么吗?另外,只是好奇......有没有办法删除 & >额外的?
  • 如果你最终得到&amp;amp; &amp;gt; extras,可能是字符串已经用htmlspecialchars 编码了两次。您可以使用htmlspecialchars_decode 摆脱它们。但是当你这样做时要非常小心!这可能会再次向 javascript 注入攻击打开字符串。找出错误应用第二个htmlspecialchars 的位置几乎总是更好。
  • @Rodin 谢谢,你是第一个真正把这个放到每个代码实际作用的例子中的人。非常感谢。它有助于理解如何正确使用这些。我相信很多其他人也会欣赏你的努力。
  • @Rodin 我有一个问题,你使用 print,它的作用与 echo 正确吗?
【解决方案2】:

关键是要了解您可以使用的每个消毒功能的用途,以及应在何时使用。例如,数据库转义函数旨在使数据可以安全地插入数据库,因此应该这样使用;但是 HTML 转义函数旨在消除恶意 HTML 代码(如 JavaScript),并确保输出数据以供用户查看。在正确的时间对正确的事物进行消毒。*

  • 您可以采用两种不同的基本方法:您可以在收到 HTML 时对其进行清理,或者您可以完全按照收到的内容存储它并仅在需要将其输出给用户时对其进行清理。这些方法中的每一种都有其支持者,但第二种方法可能最不容易出现问题(对于第一种方法,如果在您的清理过程中发现缺陷并且您发现您的数据库中存储的内容清理不足,您会怎么做? ?)

可以使用日期解析功能对日期进行清理。在 PHP 中,您可能会查看 strtotime()。您的目标通常是获取日期的字符串表示形式,并输出表示日期的对象或以规范方式(即:以特定格式)表示同一日期的另一个字符串。

【讨论】:

  • 好的...我希望插入一个语句,该语句将允许像我现在所做的语句这样的字符。就是这样,然后允许查看此语句。消毒期间。
  • 所以你有两个脚本:一个接收内容(消息)并将其插入数据库,一个检索内容并显示它。第一个脚本是将数据发送到数据库,因此它需要使用数据库转义函数来使数据以这种方式安全使用。第二个脚本正在向用户的浏览器发送数据,因此它需要使用 HTML 转义函数来消除浏览器处理该数据可能会伤害用户的可能方式。然而,HTML 转义并不是唯一需要考虑的事情。查找跨站请求伪造。
  • 我在一页中执行此操作,而不是多页,如果我明白你在说什么...虽然我不想这么说,我已经查看了你的建议。如果我一开始不明白如何正确回答原始问题,我真的不需要另一种方法。
【解决方案3】:

关于日期的清理,PHP 有一些可以提供帮助的内置函数。 strtotime() 函数会将几乎任何可以想象的日期/时间格式转换为 Unix 时间戳,然后可以将其传递给 date() 函数以将其转换为您喜欢的任何格式。

例如:

$date_sql = date("Y-m-d", strtotime($_POST["date"]));

【讨论】:

  • 但这能防止注射吗?
  • 这实际上与注入无关,因为它发生在 PHP 级别。如果您希望防止注入,我建议您使用准备好的语句,这些语句在 php_mysqli 扩展中受支持。
  • 哦,更简短的回答是:是的,这可以防止注射,因为(至少据我所知)日期(“Ymd”),无论其输入如何,都不会输出任何可能在 SQL 注入攻击中很有用。 =)
猜你喜欢
  • 2022-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-12
  • 2021-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多