何时过滤/清理数据:在数据库插入之前或显示之前?

时间:2009-08-13 21:02:58

标签: php html filter sanitize

当我准备解决输入数据过滤和清理问题时,我很好奇是否有最佳(或最常用)的做法?在将数据插入数据库之前过滤/清理数据(HTML,JavaScript等)是否更好,还是应该在准备好以HTML格式显示数据时进行?

一些注意事项:

  • 我在PHP中这样做,但我怀疑这个问题的答案是语言不可知的。但是,如果您有任何特定于PHP的建议,请分享!
  • 这不是转义数据库插入数据的问题。我已经很好地处理了PDO。

谢谢!

6 个答案:

答案 0 :(得分:19)

在显示用户提交的数据时,普遍接受的口号是“过滤输入,转义输出。”

我建议在进入数据库之前不要转义像html实体之类的东西,因为你永远不知道什么时候HTML不会成为你的显示媒体。此外,不同类型的情况需要不同类型的输出转义。例如,在Javascript中嵌入字符串需要与HTML中不同的转义。之前这样做可能会让自己陷入虚假的安全感。

因此,基本的经验法则是,在使用前进行消毒,特别是用于该用途;不是先发制人。

(请注意,我不是在讨论转义SQL的输出,只是为了显示。还是要转义绑定SQL字符串的数据)。

答案 1 :(得分:11)

我喜欢以原始形式存储/存储数据。 我只根据我使用它的位置来逃避/过滤数据。

  • 在网页上 - 编码所有html
  • on sql - kill quotes
  • on url - urlencoding
  • 打印机上的
  • - 编码转义命令
  • 关于什么 - 为该工作编码

答案 2 :(得分:7)

您应该关注至少两种类型的过滤/清理:

  • SQL
  • HTML

显然,在将数据插入数据库之前/之前必须注意第一个,以防止SQL注入。
但是你已经知道了,正如你所说的那样,所以我不再谈论它了。


另一方面,第二个是一个更有趣的问题:

  • 如果您的用户必须能够编辑他们的数据,那么将它们返回给他们是有趣的,就像他们最初输入数据一样;这意味着你必须存储一个“非html-specialchars-escaped”版本。
  • 如果你想显示一些HTML,你可能会使用像HTMLPurifier这样的东西:非常强大......但是如果你在每个数据上运行它时可能需要一点点资源显示......

所以:

  • 如果你想显示一些HTML,使用繁重的工具来验证/过滤它,我会说你需要将已经过滤的/无论什么版本存储到数据库中,以免破坏服务器,重新创建每个显示数据的时间
    • 但您还需要存储“原始”版本(请参阅我之前说过的内容)
    • 在这种情况下,我可能会将两个版本存储到数据库中,即使它需要更多的地方......或者至少使用一些好的缓存机制,不要一遍又一遍地重新创建干净的版本。
  • 如果您不想显示任何HTML,您将使用htmlspecialchars或等效的,这可能不是那么多的CPU使用者......所以它可能并不重要
    • 您仍然需要存储“原始”版本
    • 但在输出数据时转义可能没问题。
顺便说一句,如果用户在输入数据时使用类似bbcode / markdown / wiki的东西,那么第一个解决方案也很不错,而且你用HTML呈现它...
至少,只要它显示的频率高于更新频率 - 特别是如果你不使用任何缓存来存储干净的HTML版本。

答案 3 :(得分:6)

在将数据库放入数据库之前,将其清理为数据库(如果您没有使用为您处理的数据库交互层)。在显示之前清理它以进行显示。

以目前不必要的引用形式存储东西只会导致太多问题。

答案 4 :(得分:6)

我总是说在将它们传递到需要逃脱的地方之前立即逃避。您的数据库不关心HTML,因此在存储到数据库之前转义HTML是不必要的。如果您希望输出HTML以外的内容,或者更改允许/禁止哪些标记,您可能需要先做一些工作。此外,当需要完成时,比在过程的早期阶段更容易记住进行转义。

值得注意的是,HTML转义字符串可能比原始输入长得多。如果我在注册表单中放入日语用户名,原始字符串可能只有4个Unicode字符,但HTML转义可能会将其转换为长字符串“〹𐤲䡈& #31337;”。那么我的4个字符的用户名对于你的数据库字段来说太长了,并且存储为两个日文字符加上一半的转义码,这也可能阻止我登录。

请注意,浏览器往往会在提交的表单中忽略某些非英语文本等内容,并且总会有智能手机在任何地方使用日语用户名。因此,您可能希望在存储之前实际 unescape HTML。

答案 5 :(得分:4)

主要取决于您计划对输入以及开发环境进行的操作。

在大多数情况下,您需要原始输入。通过这种方式,您可以将输出调整到心脏的内容,而不必担心丢失原始内容。这也允许您解决输出损坏等问题。您可以随时查看过滤器的错误或客户的输入是错误的。

另一方面,可以立即过滤一些短语义数据。 1)你不希望数据库中出现凌乱的电话号码,所以对于这样的事情来说,清理它可能是件好事。 2)您不希望其他程序员在没有转义的情况下意外输出数据,并且您在多程序员环境中工作。但是,对于大多数情况,原始数据是更好的IMO。