Javascript中的简单HTML清理程序

San*_*hal 28 html javascript wmd html-sanitizing

我正在寻找一个用JavaScript编写的简单HTML清理程序.它不需要100%XSS安全.

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

无需具有完整XSS保护的完整解析器.我不是将输出发送回服务器.在将结果存储到数据库之前,我将Markdown发送到我使用正确的完整HTML清理程序的服务器.

谷歌对我来说绝对没用.我只收到数百条(通常是不正确的)文章,介绍如何从各种服务器端语言的用户生成的HTML中过滤掉javascript.

UPDATE

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

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

<script>alert('Boo!');</script>
Run Code Online (Sandbox Code Playgroud)

MarkDown转换器不会触及它,因为它是HTML.HTML清理程序将删除它,以便脚本元素消失.

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

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

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

你能帮我吗?提前致谢!

Ale*_*lex 15

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

用法

var result = HtmlSanitizer.SanitizeHtml(input);
Run Code Online (Sandbox Code Playgroud)

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


Mic*_*lon 14

您应该查看此问题中建议的那个在客户端清理/重写HTML

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


fee*_*ela 11

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

const inputString = 'Some text <b><i>with</i></b> <blink>tags</blink>,, including a rogue script <script>alert(1)</script> def.';
const result = new Sanitizer().sanitizeToString(inputString);
console.log(result);
// Logs "Some text <b><i>with</i></b>, including a rogue script def."
Run Code Online (Sandbox Code Playgroud)

(MDN 示例)

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

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


Nic*_*ele 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>

Run Code Online (Sandbox Code Playgroud)

作为对比,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
Run Code Online (Sandbox Code Playgroud)

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

  • 呃...我不仅谈论清理,实际上我还提供了一个提到的确切用例的示例...对 markdown 进行清理,并且我在 &lt; 2kb 内完成了它;比其他任何人都小得多,非常干净,并且可以防止 XSS。答案实际上涵盖了整个问题。我认为很容易争论我的答案是十多年来提供的唯一完整答案。你因为我也提到删除而投票给我?这对社区有帮助吗?:/如果你把你的车送去换油并且他们提到你有垫圈泄漏,你会否决你的机械师吗?严厉的兄弟。 (3认同)
  • 问题是关于 html 清理,而不是删除 (2认同)
  • 这是“逃避”,而不是“净化”。https://en.wikipedia.org/wiki/HTML_sanitization 甚至 Snarkdown 主页也显示“Snarkdown 不会清理 html” (2认同)