Дезинфицировать недоверенные HTML - PullRequest
0 голосов
/ 13 июня 2019

У меня есть недоверенная строка html, которую я хочу отобразить в iframe. Iframe не может быть помещен в песочницу, потому что он должен увеличиваться в высоте в зависимости от содержимого, которое, насколько я знаю, требует JavaScript.

Так что мне нужно санировать ненадежный html, чтобы было безопасно включить его в iframe. Любой javascript должен быть удален из html, но ничто не должно быть удалено из html / css, который изменит способ его рендеринга (если это не что-то небезопасное).

Я нашел пакет sanitize-html, который требует от вас вручную решить, что разрешено, а что нет. Это кажется очень подверженным ошибкам с точки зрения взлома html / css, что на самом деле безопасно, а также склонно к ошибкам, позволяющим делать вещи, которые на самом деле небезопасны.

Какой распространенный способ решения этой проблемы? Существуют ли стандартные конфигурации?

1 Ответ

0 голосов
/ 13 июня 2019

Вы можете использовать встроенные функции 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>
...