过滤器输入转义输出,或转义输入过滤器输出


Filter input escape output, or escape input filter output?

我有点困惑。当我在谷歌上打字时,几乎所有的文章都建议使用Filter input, escape output.。如果我一辈子都没有混淆转义和过滤这两个术语,那应该是相反的。

你会得到很多像一样的文章

$username = htmlentities(htmlspecialchars(strip_tags($_POST['username')));

并建议这样做。

  1. 我们不应该过滤输入。我们应该对其进行转义(以前我们使用mysql_real_escape_string进行转义,现在准备好的语句为我们处理它们。)我们应该将用户提交的数据插入数据库as-is,而不使用htmlspecialchars等函数对其进行更改。我们应该始终将原始输入保存在数据库中,因此输入过程中的htmlspecialchars是错误的。HTML对数据库无害。

  2. 我们应该过滤输出,这样恶意代码(html、js等)就不会在浏览器上运行。这被称为XSS filtering,而不是XSS escaping。例如,Laravel 4上的{{{ $var }}}被称为XSS filtering,这应该始终用于用户提交的内容的输出。

如果语句Filter input escape output是正确的,为什么它不是mysql_real_filter_string(),并且防止XSS没有被调用为XSS escaping

此外,ircmaxell曾经说过:

筛选不是为了防止安全漏洞,而是为了不在数据库中填充垃圾。如果你期待一个日期,在存储它之前,确保它至少看起来像一个日期

这被称为validation,并且不能仅依赖于验证。(尤其是在旧版本的PHP上)您需要对输入进行转义和验证。筛选可能不用于安全漏洞,但可以进行转义。

好吧,这总结了我的困惑。有人能向我解释一下吗?

看起来我的困惑很简单。当我们开始使用echo的时,我认为输出层就是那个层,比如视图层。

根据Anthony Ferrara的说法,输出是数据离开应用程序的那一层,输入是数据进入应用程序的这一层。

因此,Input层不仅限于用户提供的内容,而且从配置文件读取、从文件系统读取、从第三方API检索数据等都被认为是Input

CCD_ 18不限于视图层上的CCD_ 19或CCD_。SQL queries也算作output,因为数据离开我们的应用程序并进入数据库的范围。因此,写入文件也算作输出,执行shell命令也算作输出。

所以基本上,查询数据库是Output,而从数据库中检索结果是Input

当你这样想的时候,Filter input, escape output听起来是正确的。如果其他人和我一样感到困惑,这真的很有道理。

首先:htmlentitieshtmlspecialchars实际上不转义字符串,它们将特定字符转换为html实体!

  1. 首先,您应该接受用户输入,并删除伪/自动的"安全"类魔术引号。

    if (get_magic_quotes_gpc())
    {
        $lastname = stripslashes($_POST['lastname']);
        // ...
    }
    

    这样就可以获得"纯"或原始用户输入。

  2. 那么过滤意味着例如不允许fooBar之类的内容作为电子邮件地址!

    if (!my_own_email_validity_check($_POST['email'])) die(); // maybe a bit extreme
    
  3. 之后转义要存储的用户输入(例如在数据库中)

    $city = $mysqli->real_escape_string($city);
    

    或者最好使用PDO,它"自动"完成:-)

  4. 但真正重要的部分是,当向用户显示数据库中的数据时,请确保您通过htmlspecialchars()运行所有数据,因为您无法确定其中的任何内容是否正常!!!

现在有其他观点认为,当你获得原始数据时,你应该立即运行htmlentities,但这让处理它变得可怕,而且不是推荐的方法。但这甚至可能取决于你在做什么,就像做很多事情一样。

所以总结一下,总的来说:

  • 存储时,您需要转义用户输入,这样您就可以安全地避免注入
  • 显示时,您需要转换存储的数据,以防XSS

编辑:命名也有很多不同,有时人们在逃离时称之为过滤,或者在净化时称其为一般的逃离,等等。所以不要被命名所混淆,只要了解发生了什么,你就会没事的;-)

编辑2: 回答您的问题:

它被称为"过滤器输入,转义输出",因为。。。

  • 在这种情况下,过滤实际上意味着不允许数据库中出现"错误"数据。(比如第2点,电子邮件验证、邮政编码,这些都是你可以排除的。以后可能会打乱你的数据处理!)
  • Escape输出是为了防止XSS->实际转换为html实体,所以这里是一个命名的例子
  • 在"filter input,escape output"中,要么不考虑转义以防止SQL注入,要么甚至用"filtering"来概括它(正如您所说,这不是正确的术语(imho))

在我看来,问题是命名不一致。

过滤输入转义输出以防止存储不可信的、注入的坏数据,同时防止跨站点脚本(XSS)http://shiflett.org/blog/2005/filter-input-escape-outputhttp://shiflett.org/blog/2005/more-on-filtering-input-and-escaping-output

过滤输入并不意味着不通过转义来净化SQL插入。这只是一个朗朗上口、简洁明了的最佳实践,要记住认真负责。Chris Shiflett并没有说你永远不会逃避输入或过滤输出。