javascript - 使用 DocumentFragment 和 innerHTML 通过富文本注释存储 XSS 预防

标签 javascript xss innerhtml richtext

我想知道是否有人能够确认这是否安全,因为我似乎无法在网上找到任何引用资料,也找不到关于 SO 的另一个问题,专门处理 XSS 的“解决方案”。

我需要将富文本评论嵌入到我的页面中。显然,XSS 的风险很高,所以我的计划是在 DocumentFragment 中将临时 DIV 嵌入 HTML,然后使用我认为“安全”的预定义标记名和属性名称白名单来递归树,删除任何不安全的。然后我可以将这个现在安全的 HTML 移动到我的真实文档中。

这是一种安全的做法吗?有什么方法可以通过 DocumentFragment 来触发 XSS 攻击吗?我希望它将与真实文档隔离,从而避免可能引发任何攻击的用户事件触发。

最佳答案

我不建议您编写自己的反 XSS 库,因为恶意用户一定会知道您没有考虑到的漏洞。我建议使用第三方库,例如 Google Caja HTML Sanitiser .

查看您的 Pen 后,您的代码仍然容易受到攻击,如果 <>标签被转义:

var unsafe = '\u003Cimg src=1 onerror=alert(\u0027XSS_attack_in_progress\u0027)\u003E',
  //var unsafe = '<h3>Hello</h3><h4>World</h4>',
  whitelistTags = ['h1', 'h2', 'h3', 'b', 'i', 'em', 'strong', 'u'],
  testNode = document.getElementById('testNode');

makeSafeAndAddToDoc(unsafe, testNode);

function makeSafeAndAddToDoc(unsafe, targetParent) {
  var safeDocFrag = document.createDocumentFragment(),
    containerDiv = safeDocFrag.appendChild(document.createElement("DIV")),
    nextChild;
  containerDiv.innerHTML = unsafe;
  while ((nextChild = containerDiv.firstChild)) {
    if (isSafe(nextChild)) {
      safeDocFrag.appendChild(containerDiv.firstChild);
      console.debug(safeDocFrag.children);
    } else {
      containerDiv.removeChild(nextChild);
    }
  }
  safeDocFrag.removeChild(containerDiv);
  targetParent.appendChild(safeDocFrag);
}

function isSafe(testNode) {
  var tag = testNode.tagName && testNode.tagName.toLowerCase(),
    isTextNode = testNode.nodeType === 3;
  if (!isTextNode && whitelistTags.indexOf(tag) === -1) {
    console.warn('Removing unsafe element: ', testNode.tagName);
    return false;
  }
  for (var i = 0; i < testNode.childNodes.length; i++) {
    if (!isSafe(testNode.childNodes[i])) {
      testNode.removeChild(testNode.childNodes[i]);
      i--;
    }
  }
  return true;
}
#testNode {
  min-width: 10px;
  min-height: 10px;
  border: 1px solid red;
}
<div id="testNode"></div>

关于javascript - 使用 DocumentFragment 和 innerHTML 通过富文本注释存储 XSS 预防,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29816651/

相关文章:

javascript - 保持表头可见而不在表体中显示滚动条

javascript - 当涉及特殊字符时,如何比较 JavaScript insideHTML 返回值?

javascript - 从 Javascript 函数创建一个 div (innerHTML)

angularjs - Angular 翻译指令与过滤器 : is XSS possible?

javascript - 如何捕获来自另一个域的 iframe 的点击?

jQuery 父级更改内部 HTML

javascript - 使用 node-soap 在 Node.js 中通过 Soap 发送参数

javascript - 了解 HTML Retina Canvas 支持

javascript - jquery slider 和 amchart 的问题

javascript - createTextNode 对 HTML 注入(inject)和 XSS 完全安全吗?