leizongmin / js-xss

Sanitize untrusted HTML (to prevent XSS) with a configuration specified by a Whitelist
http://jsxss.com
Other
5.19k stars 630 forks source link

提供选项允许校验标签的完整性? #231

Open undefined-moe opened 3 years ago

undefined-moe commented 3 years ago

如题。 xss.process('<div></div></div>') 会返回 <div></div></div> 。这会严重影响页面显示。希望能够检查开闭标签的对应关系并移除孤立的标签。

leizongmin commented 3 years ago

处理标签开闭对应关系这个会使得 HTML 解析器变得更复杂。我还是希望 js-xss 这个模块能尽可能保持简单和高性能,所以类似这种功能暂时不会考虑支持。

undefined-moe commented 2 years ago

以下提供一个简单的思路:

const stack = [];

const xss = new Xss.FilterXSS({
  whiteList: [ ... ],
  onTag(tag, html, options) {
    if (!options.isWhite) return null;
    if (!options.isClosing) {
      stack.push(tag);
      return null;
    }
    if (stack.length === 0) return `&lt;/${tag}&gt;`; // 没有标签可供闭合
    if (stack[stack.length - 1] === tag) {
      stack.pop(); // 正常关闭
      return null;
    }
    if (stack.length - 2 >= 0 && stack[stack.length - 2] === tag) {
      // 可能丢失了一个结束标签,更为复杂的情况不作处理
      stack.pop();
      stack.pop();
      return null;
    }
    return `&lt;/${tag}&gt;`; // 可能多出了一个结束标签
  },
});

xss.process = ((p) => (html: string) => {
  stack.length = 0;
  return p(html) + stack.map((i) => `</${i}>`).join('');
})(xss.process.bind(xss));
fengmk2 commented 2 years ago

xml 格式没有写对,跟 xss 什么关系?

undefined-moe commented 2 years ago

通常来说引用此模块的地方都是接受用户输入过滤之后直接插入页面的,我们引入此模块,目的是防止用户输入干扰页面正常工作(而不仅仅是通常意义上的防止 <script> 注入)。

在现代浏览器中,若使用 node.innerHTML = 'xxx',浏览器会自动处理标签层级关系,但若用于后端渲染直出 HTML 的情景,标签不闭合或多闭合都会直接破坏页面层级结构,干扰页面元素布局。

考虑到现代化 UI 设计大多都会使用 SPA 方案,此功能不一定有并入主线的必要,但可提供在此供有需要的人使用。

leizongmin commented 2 years ago

@undefined-moe 这个xss模块主要作用是过滤可能存在xss注入的HTML,在这个基础上甚至可能带来一些副作用,比如由于输入了不规范的HTML而导致某些标签被转义(例如页面显示异常)。这个模块不会考虑增加诸如修复HTML格式这类的功能。