【问题标题】:Filter input escape output, or escape input filter output?过滤输入转义输出,还是转义输入过滤输出?
【发布时间】:2014-06-15 05:23:27
【问题描述】:

我有点困惑。当我在谷歌上打字的时候,几乎所有的文章都建议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 上)您需要转义和验证输入。过滤可能不能用于安全漏洞,但转义是。

嗯,这总结了我的困惑。谁能给我解释一下?

【问题讨论】:

    标签: php filter


    【解决方案1】:

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

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

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

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

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

    当您这样想时,Filter input, escape output 听起来是正确的。如果其他人像我一样感到困惑,这真的很有意义。

    【讨论】:

      【解决方案2】:

      首先: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 点,电子邮件验证,邮政编码,您可以排除的事情。以后也可能会扰乱您的数据处理的事情!)
      • 转义输出是为了防止XSS -> 所以实际上是转换为html实体,所以这里是命名的情况
      • 在“过滤输入,转义输出”中,要么不考虑转义以防止 SQL 注入,要么甚至用“过滤”进行总结(正如您所说,这不是正确的术语(恕我直言))

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

      【讨论】:

      • 说实话,这就是我在我的主题中所说的。
      • 是的,我同意你的看法!我只是在完成这些步骤并为每个人命名以清楚起见。例如,在您的问题上,为什么不将其称为“mysql_real_filter_string()”,它当然会对其进行转义(3)而不是过滤。所以你是对的!我将编辑我的答案以提供对您问题的实际答案,而不仅仅是演示......
      • 老实说...Levit 说得好多了。
      • 我们不能修剪、剥离标签和 htmlspecialchars,然后转义并插入数据库。或者这不是正确的方法?
      • @Luka: 那么 htmlspecialchars 或 htmlentities 实际上是用于 html 以防止 xss 攻击等。如果你如果在数据库中有这样的内容,您必须意识到所有“非输出到 html 的操作”与数据可能不符合预期(例如在该文本中搜索或比较等)。
      【解决方案3】:

      过滤输入转义输出以防止存储不受信任、注入的不良数据,同时防止跨站点脚本 (XSS)

      【讨论】:

        【解决方案4】:

        查看该短语最初使用的上下文可能会有所帮助: http://shiflett.org/blog/2005/filter-input-escape-output http://shiflett.org/blog/2005/more-on-filtering-input-and-escaping-output

        过滤输入并不意味着您不会通过转义来清理 SQL 插入。记住要认真负责,这只是一个吸引人的、简洁的最佳实践。 Chris Shiflett 并没有说你永远不会转义输入或过滤输出。

        【讨论】:

          猜你喜欢
          • 2011-02-23
          • 2014-04-14
          • 2011-05-12
          • 2011-04-25
          • 2012-06-30
          • 1970-01-01
          • 1970-01-01
          • 2014-01-17
          • 2012-02-07
          相关资源
          最近更新 更多