HTML 是不是应该在持久化之前进行编码?

Posted

技术标签:

【中文标题】HTML 是不是应该在持久化之前进行编码?【英文标题】:Should HTML be encoded before being persisted?HTML 是否应该在持久化之前进行编码? 【发布时间】:2011-02-06 15:58:10 【问题描述】:

在存储到数据库之前是否应该对 html 进行编码?还是在输出到浏览器时进行编码是正常的做法?

是否应该将我所有基于文本的字段长度在数据库中增加四倍以允许额外的存储空间?

寻找最佳实践,而不是确定是或否:-)

【问题讨论】:

最佳实践通常是社区 wiki。 :) 【参考方案1】:

我不同意所有认为应该在显示时对其进行解码的人的观点,如果在其到达数据库之前对其进行编码,则只有在开发人员在显示之前对其进行解码时才有可能发生攻击。但是,如果您在呈现之前对其进行解码,则其他新手开发人员总是有可能发生这种情况,例如新员工或糟糕的实现。如果它坐在那里未编码,它只是等待在互联网上弹出并像疱疹一样传播。丢失原始数据不应该是一个问题。编码 + 解码每次都应该产生相同的数据。只是我的两分钱。

【讨论】:

【参考方案2】:

您的数据库中的数据是真正的 HTML 数据,还是您碰巧知道的名称或评论等应用程序数据最终会成为 HTML 页面的一部分?

如果是应用数据,我认为最好:

以环境原生的形式表示它(例如在数据库中未编码),并且 确保其在跨越代表性边界时正确翻译(在生成 HTML 页面时进行编码)。

如果您是 MVC 的粉丝,这也有助于将视图/控制器与模型(以及持久存储格式)分开。

代表

例如,假设有人留下评论“我爱 M&Ms”。在代码中将其表示为纯文本字符串 "I love M&Ms" 可能最容易,而不是 HTML 编码的字符串 "I love M&Ms"。从技术上讲,代码中存在的数据还不是 HTML,如果数据尽可能准确地表示,生活是最容易的。此数据稍后可能会在不同的视图中使用,例如桌面应用程序。这些数据可能存储在数据库、平面文件或 XML 文件中,以后可能会与另一个程序共享。对于其他程序来说,最简单的方法是假设字符串是格式的“本机”表示:"I love M&Ms" 在数据库和平面文件中,"I love M&Ms" 在 XML 文件中。看到在 XML 文件 ("I love &Ms") 中编码的 HTML 编码值,我会感到畏缩。

翻译

稍后,当数据即将跨越表示边界时(例如以 HTML 显示、存储在数据库、纯文本文件或 XML 文件中),那么确保它很重要被正确翻译,因此它以下一个环境的原生格式准确表示。简而言之,当您将其显示在 HTML 页面上时,请确保将其翻译为正确编码的 HTML(手动或通过工具),以便该值准确显示在页面上。当您将其存储在数据库中或在查询中使用它时,请使用转义和/或准备好的语句和绑定变量来确保将相同的概念值准确地表示到数据库中。当您将其存储在 XML 文件中时,请确保它是 XML 编码的。

跨越表示边界时未能正确转换是注入攻击的来源,例如 SQL 注入攻击。每当您使用多种表示/语言(例如 Java、SQL、HTML、javascript、XML 等)时,请注意这一点。

--

另一方面,如果您真的想将 HTML 页面片段保存到数据库中,那么我不清楚您所说的“在存储之前编码”是什么意思。如果它是严格有效的 HTML,则所有必要的值都应该已经编码(例如 &< 等)。

【讨论】:

【参考方案3】:

数据库供应商特定的输入转义,html 输出转义。

【讨论】:

【参考方案4】:

做法是在显示之前进行HTML编码。

如果您在显示之前对编码保持一致,那么您已经做了很好的XSS预防。

您应该将原始表单保存在数据库中。这保留了原始版本,您可能希望在 that 上而不是在编码版本上进行其他处理。

【讨论】:

嗯,我试图避免对每个请求进行编码,将其视为重复性任务。不过有趣的是:) +1 最好在显示时编码而不是在存储时编码,因为如果您需要以不同方式处理它,您将拥有原始数据。【参考方案5】:

出于安全原因,是的,您应该首先将 html 转换为其实体,然后插入到数据库中。当您允许用户(或者更确切地说是坏人)使用 html 标签然后您将它们处理/插入到数据库中时,就会发起诸如 XSS 之类的攻击。 XSS 是大多数安全漏洞的根本原因之一。所以你肯定需要在存储之前对你的 html 进行编码。

【讨论】:

这可能并不总是好的,因为我在这里丢失了原始数据! @Mahesh 如果原始数据是 XSS 攻击怎么办? 将恶意 HTML 插入数据库不会带来安全风险。仅将恶意 HTML 呈现给浏览器就是其中之一。因此,在将 HTML 插入数据库时​​,不需要将 HTML 特殊字符替换为字符引用。只有 SQL 的上下文特殊字符需要替换/转义。

以上是关于HTML 是不是应该在持久化之前进行编码?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有密码编码的情况下使用 Spring 安全性?

RESTKit:在覆盖之前将 GET 对象与本地持久化的对象进行比较

在 Hibernate 中持久化 Joda DateTime 而不是 Java Date

如何在 symfony2 中持久化之前设置列值?

将图像添加到 HTML5 持久存储中

应该如何对列表中的项目进行重新排序,并更新多个对象,如何使用 GraphQL 突变进行持久化?