46

我正在寻找一个用 JavaScript 编写的简单的 HTML sanitizer。它不需要 100% XSS 安全。

我正在我的网站上实现 Markdown 和 WMD Markdown 编辑器(来自 github 的 SO 主分支)。问题是实时预览中显示的 HTML 没有被过滤,就像它在 SO 上一样。我正在寻找一个用 JavaScript 编写的简单/快速的 HTML sanitizer,以便我可以过滤预览窗口的内容。

不需要具有完整 XSS 保护的完整解析器。我没有将输出发送回服务器。在将结果存储在数据库中之前,我将 Markdown 发送到使用适当的、完整的 HTML 清理程序的服务器。

谷歌对我来说绝对没用。我刚刚收到数百篇(通常不正确)关于如何从用户生成的各种服务器端语言的 HTML 中过滤掉 javascript 的文章。

更新

我会更好地解释为什么我需要这个。我的网站有一个与 StackOverflow 上的非常相似的编辑器。有一个文本区域可以输入 MarkDown 语法,它下面有一个预览窗口,显示提交后的样子。

当用户提交内容时,它会以 MarkDown 格式发送到服务器。服务器将其转换为 HTML,然后在其上运行 HTML sanitizer 以清理 HTML。MarkDown 允许任意 HTML,所以我需要清理它。例如,用户键入如下内容:

<script>alert('Boo!');</script>

MarkDown 转换器不会触及它,因为它是 HTML。HTML sanitizer 将删除它,因此脚本元素消失了。

但这不是预览窗口中发生的情况。预览窗口仅将 MarkDown 转换为 HTML,但不会对其进行清理。因此,预览窗口将有一个脚本元素。这意味着预览窗口与服务器上的实际呈现不同。

我想解决这个问题,所以我需要一个快速又脏的 JavaScript HTML sanitizer。一些简单的基本元素/属性黑名单和白名单就可以了。它不需要 XSS 安全,因为 XSS 保护是由服务器端 HTML sanitizer 完成的。

这只是为了确保预览窗口在 99.99% 的时间内与实际渲染相匹配,这对我来说已经足够了。

你能帮我吗?提前致谢!

4

4 回答 4

17

你应该看看这个问题中推荐的一个在客户端上清理/重写 HTML

并且只是为了确保您不需要对 XSS 做更多的事情,请查看这个如何防止用户生成的 HTML 中的 Javascript 注入攻击的答案

于 2009-10-28T14:23:57.030 回答
16

我们开发了一个简单的 HtmlSantizer 并在这里开源:https ://github.com/jitbit/HtmlSanitizer

用法

var result = HtmlSanitizer.SanitizeHtml(input);

[免责声明!我是作者之一!]

于 2019-01-18T14:37:22.613 回答
5

这是一个 2kb(取决于 Snarkdown,它是一个 1kb 降价渲染器,替换为您需要的)vue 组件,它将渲染转义的降价,甚至可以选择翻译 B 和 I 标记的内容,其中可能包含那些带有格式的标记...

<template>
  <div v-html="html">
  </div>
</template>

<script>
import Snarkdown from 'snarkdown'
export default {
  props: ['code', 'bandi'],
  computed: {
    html () {
      // Convert b & i tags if flagged...
      const unsafe = this.bandi ? this.code
        .replace(/<b>/g, '**')
        .replace(/<\/b>/g, '**')
        .replace(/<i>/g, '*')
        .replace(/<\/i>/g, '*') : this.code

      // Process the markdown after we escape the html tags...
      return Snarkdown(unsafe
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;')
      )
    }
  }
}
</script>

作为对比,vue-markdown 超过 100kb。这不会渲染数学公式等,但 99.99% 的人不会将它用于这些事情,所以不确定为什么最流行的降价组件如此臃肿:(

这对 XSS 攻击是安全的,而且速度非常快。

为什么我使用&#039;而不使用&apos;?因为:为什么不应该使用 `'` 来转义单引号?

现在对于一些完全不同但相关的东西......

不知道为什么还没有提到这一点……但是您的浏览器可以为您清理。

这是 3 行 HTML 清理程序,通过使用浏览器附带的汇编语言版本,它的清理速度比任何 JavaScript 变体快 30 倍……这用于 Vue/React/Angular 和许多其他 UI 框架。请注意,这不会转义 HTML,它会删除它。

const decoder = document.createElement('div')
decoder.innerHTML = YourXSSAttackHere
const sanitized = decoder.textContent

作为这种方法被接受且速度快的证明,这里是 Vue.js 中使用的解码器的实时链接,它使用相同的模式:https ://github.com/vuejs/vue/blob/dev/src/compiler/parser/实体解码器.js

于 2020-04-29T23:45:39.087 回答
3

另一个提示:截至 2021 年 5 月,Firefox 中即将推出 Sanitizer API。

// our input string to clean
const stringToClean = 'Some text <b><i>with</i></b> <blink>tags</blink>,, including a rogue script <script>alert(1)</script> def.';

const result = new Sanitizer().sanitizeToString(stringToClean);
console.log(result);
// Logs: "Some text <b><i>with</i></b>, including a rogue script def."

(MDN 示例)

请参阅:https ://developer.mozilla.org/en-US/docs/Web/API/HTML_Sanitizer_API

如果其他供应商也接受此功能,它可能会帮助我们摆脱 JS-sanitizer-implementations。

于 2021-05-09T13:13:42.787 回答