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

Posted

技术标签:

【中文标题】何时过滤/清理数据:在数据库插入之前还是在显示之前?【英文标题】:When to filter/sanitize data: before database insertion or before display? 【发布时间】:2010-11-19 11:04:14 【问题描述】:

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

几点说明:

我在 php 中执行此操作,但我怀疑此问题的答案与语言无关。但是如果您有任何针对 PHP 的建议,请分享! 这不是为了数据库插入而转义数据的问题。我已经让 PDO 处理得很好。

谢谢!

【问题讨论】:

查看我的回复:***.com/questions/129677/… 【参考方案1】:

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

在网页上 - 编码所有 html 关于 sql - 杀死引号 在 url - urlencoding 在打印机上 - 编码转义命令 关于什么 - 为该工作编码

【讨论】:

【参考方案2】:

如有必要,在将其放入数据库之前对其进行清理(即,如果您没有使用为您处理该问题的数据库交互层)。展示前对其进行消毒。

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

【讨论】:

【参考方案3】:

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

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

因此,基本的经验法则是,在使用前进行消毒,并专门针对该用途进行消毒;不要先发制人。

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

【讨论】:

+1 总体上非常棒的提示,尤其是“我建议不要在进入数据库之前转义 html 实体等内容,因为您永远不知道 HTML 何时不会成为您的显示媒体”跨度> 【参考方案4】:

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

SQL HTML

显然,在将数据插入数据库之前/期间必须注意第一个,以防止 SQL 注入。 但你已经知道了,正如你所说,所以我不会多说。

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

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

所以:

如果您想显示一些 HTML,使用重型工具对其进行验证/过滤,我想说您需要将已过滤/任何版本存储到数据库中,以免破坏服务器,重新创建每个数据显示时间 但您还需要存储“原始”版本(请参阅我之前所说的) 在这种情况下,我可能会将两个版本都存储到数据库中,即使它需要更多的空间......或者至少使用一些好的缓存机制,而不是一遍又一遍地重新创建干净的版本。 如果您不想显示任何 HTML,您将使用 htmlspecialchars 或等效项,这可能不是 CPU 消耗者...所以这可能无关紧要 您仍然需要存储“原始”版本 但在输出数据时转义可能没问题。

顺便说一句,如果用户在输入数据时使用 bbcode/markdown/wiki 之类的东西,并且您正在用 HTML 呈现它,那么第一个解决方案也很好...... 至少,只要它的显示频率高于更新频率——尤其是如果您不使用任何缓存来存储干净的 HTML 版本。

【讨论】:

(Re: 专门清理 HTML) 8 年后,现在客户端渲染如此普遍,“我想说你需要将已经过滤/任何版本存储到数据库中,而不是破坏服务器”点现在更加相关。清理 HTML 是一项代价高昂的操作,在许多情况下,在保存时清理而不是在显示时清理更有意义。在操作有损和需要数据迁移以更新清理规则方面存在明显的权衡,但在许多情况下,这些权衡是非常值得的。【参考方案5】:

这主要取决于您打算如何处理输入以及您的开发环境。

在大多数情况下,您需要原始输入。这样,您就可以根据自己的喜好调整输出,而不必担心丢失原始文件。这还允许您解决诸如输出损坏等问题。您始终可以看到您的过滤器有什么问题或客户的输入有什么错误。

另一方面,可以立即过滤一些简短的语义数据。 1)您不希望数据库中的电话号码凌乱,因此对于此类事情,清理一下可能会很好。 2)您不希望其他程序员在没有转义的情况下意外输出数据,并且您在多程序员环境中工作。然而,在大多数情况下,原始数据比 IMO 更好。

【讨论】:

【参考方案6】:

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

还值得注意的是,HTML 转义字符串可能比原始输入长得多。如果我在注册表中输入日本用户名,原始字符串可能只有 4 个 Unicode 字符,但 HTML 转义可能会将其转换为“〹

以上是关于何时过滤/清理数据:在数据库插入之前还是在显示之前?的主要内容,如果未能解决你的问题,请参考以下文章

我们应该在训练/测试拆分之前还是之后预处理文本数据? [关闭]

何时唤醒读写器问题中的作者?在释放互斥锁之前还是之后?

vue属性绑定函数何时执行

搜索过滤器在单击搜索按钮之前不会获取数据

Bootstrap-table在显示之前把数据过滤一遍,把不符合type==1的行直接不显示了。。

在 .NET 中执行测试之前清理数据库