清理不受信任的html

时间:2019-06-13 13:18:02

标签: javascript iframe sanitize

我有一个不可信的html字符串,我想在iframe中显示。无法将iframe沙盒化,因为据我所知,它需要根据需要的内容来增加高度。

因此,我需要清理不受信任的html,以使其安全地包含在iframe中。应该从html剥离任何javascript,但从html / css剥离任何javascript都不会改变它的呈现方式(除非它不安全)。

我找到了一个包sanitize-html,它需要您手动确定允许和不允许的内容。在破坏实际上是安全的html / css方面以及在允许实际上不安全的事情上都容易出错的方面,这感觉很容易出错。

解决此问题的常用方法是什么?有一些标准配置吗?

1 个答案:

答案 0 :(得分:-1)

您可以使用内置的dom函数来删除可能触发javascript的脚本标签和事件属性。这是一个快速而肮脏的示例。请参阅注释以获取解释。

document.getElementById('btn').onclick = ()=>{
  const dirty_bad_html = document.getElementById('textarea').value;
  const shiny_fresh_clean_html = sanitizeHTML(dirty_bad_html);
  document.getElementById('textarea').value = shiny_fresh_clean_html;
};

function sanitizeHTML(dirty_bad_html) {

  // Create a virtual document
  const dirty_doc = document.implementation.createHTMLDocument("Nasty dirty html");

  // Load the dirty html into the virtual document
  dirty_doc.documentElement.innerHTML = dirty_bad_html;

  // Iterate thru every element
  var dirty_elements = Array.from(dirty_doc.querySelectorAll('*'));
  dirty_elements.forEach(dirty_bad_element => {

    // Check every attribute for every element and
    // remove any attribtutes that start with "on" such as
    // onclick, onmouseover, etc since these can execute code
    for (let i = dirty_bad_element.attributes.length; i--;) {
      if (dirty_bad_element.attributes[i].nodeName.indexOf('on') === 0) {
        dirty_bad_element.removeAttribute(dirty_bad_element.attributes[i].nodeName);
      }
    }

    // Also, remove any <script> elements
    if (dirty_bad_element.tagName === 'SCRIPT') {
      dirty_bad_element.remove();
    }
  });

  // Turn it back into a string and return it.
  return dirty_doc.documentElement.outerHTML;
}
<textarea id=textarea style="width:100%;height:12em;">
<html>
  <body>
    <h1>test page</h1>
    <button onlick="alert('doin bad stuff')">
      bad stuff will happen when you click me
    </button>
    <script>alert('doin bad stuff')</script>
  </body>
</html>
</textarea>

<button id=btn>Sanitize HTML</button>