输入验证:如果我必须接受 HTML 作为输入的一部分,该怎么做?

信息安全 xss html 数据验证
2021-08-30 17:36:56

我正在编写一个接收 FHIR 数据并将其存储的服务。FHIR 是一种 HL7 医疗保健信息标准格式,根据定义包含 HTML,嵌入到 JSON 或 XML 中,(以确保文档的人类可读性

在这种情况下我应该如何执行输入验证,以仍然能够避免 XSS 和其他类似的攻击?

3个回答

根据定义,FHIR 要求您保留数据的 XSS 漏洞(存储为代码,显示为代码)。XSS 要求将数据显示给用户,而这可以通过输出验证来阻止。接受输入,存储为 JSON,在将 HTML 数据显示为 HTML 代码时进行过滤。根据“输出”系统,这可能会容易得多(这取决于系统的需要)。

过滤掉特别糟糕的代码(恶意 javascript、链接等)将非常困难。有很多方法可以通过混淆来隐藏不良代码。

根据 FHIR 规范的详细信息,您可以做的是将好的/可接受的代码列入白名单。如果 FHIR 规范被严格定义,白名单应该很容易执行。如果规范没有严格定义,则可能无法阻止存储的 XSS 的所有尝试。

我认为您应该过滤(阻止)xss 输入并在输出时转义用户提供的输入。为什么?因为数据库是长期存在的并且经常被共享,所以不应该包含 xss。Web 应用程序通常使用多个数据源。

如果您使用的是 Java,则可以使用带有JSoup的Hibernate Validator来解析和验证 HTML 输入。

它有一个WhiteListType,可让您选择允许的标签。WhiteListType.NONE不接受 HTML 标签,WhiteListType.SIMPLE_TEXT接受b, em, i, strong, u.

您也可以随时制作自己的白名单。

您最好的选择是可能不执行输入验证,但执行一些输出清理。

将脚本输出到 HTML 页面之前,可以使用诸如Google Caja 之类的消毒剂去除脚本。

由于在消毒剂中经常发现错误,通常当浏览器中的 HTML 规范或实现有新的添加或更改时,建议将其与内容安全策略结合使用这是一项 HTML5 功能,它可以防止受支持的浏览器中的 XSS 攻击,因为您可以有效地将允许运行的脚本列入白名单。用户注入的任何内容都将失败,并在浏览器控制台中出现错误。

我建议对输出而不是输入进行清理的原因是,如果您的数据库中已经有任何早期输入绕过了当时使用的清理器版本,那么以后通常可以通过将使用的清理器升级到最新版本来轻松修复. 如果您对输入进行清理,这将变得更加困难,因为您每次升级时都必须通过清理器运行所有现有的用户输入。