i'm wondering how safe it is to use createHTMLDocument to do HTML sanitization. I've tried to implement it like this:

function sanitize(string) {
  var elm = document.implementation.createHTMLDocument().body;
  elm.innerHTML = string;
  // traverse and filter elm to only allow whitelisted elements and attributes
  // e.g. use https://github.com/gbirke/Sanitize.js
  var cleaned_fragment = whitelist_filter(elm);
  elm = document.implementation.createHTMLDocument().body;

  return elm.innerHTML;

It seems to work fine with all XSS attacks i've throw at it (no script evaluation or requests triggered). But I got a feeling it might be a bad idea, im I missing something?

I've created a jsfiddle if someone wants to experiment.

  • Are you trusting a client side javascript to sanitize the HTML? If I were an attacker, I'd simply bypass the sanitization completely by not calling your function. Sanitization has to be done server-side. Feb 5, 2014 at 14:09
  • How would you bypass it? lets say this is a case where some client side javascript fetches from a server API that returns unsafe html that you would like to sanitize and insert into the page Feb 5, 2014 at 14:24
  • 2
    @JohnDeters That depends very much on the context. Html encoding can happen on the client a web application where javascript weaves the data into the html for displaying on the same machine. You could bypass it, but that'd be like a script kiddy who proudly hacks Feb 5, 2014 at 15:02
  • In the case I mention wouldn't a bug in a sanitized be equally bad either if it's done server or client side? Feb 5, 2014 at 15:05
  • Some libraries are made for that task, like DOMPurify. It use DOMParser, createHTMLDocument or toStaticHTML
    – mems
    May 17, 2017 at 15:17

2 Answers 2


You should use the DOMParser to parse HTML when available, and only fall back to DOMImplementation.createHTMLDocument if the former is unavailable.

In Opera Presto, I observed network activity when I passed <img src=...> (but not <video>).
Internet Explorer 9- is worse: media, styles and event listeners will be activated with this method. IE10+ supports DOMParser, so if your audience uses IE10+, then you're safe.

  • Thanks, did know about DOMParser. Ok good to know, i noticed that Chrome tries to fetch img tags even when in a detached dom tree but does not if in a new document. Feb 5, 2014 at 14:39
  • Did NOT know about* :) Feb 5, 2014 at 16:49
  • 1
    @MattiasWadman If you don't mind loosing lots of potentially dangerous tags and attributes, you could also try the global toStaticHTML method in IE 8 + 9.
    – Rob W
    Feb 5, 2014 at 16:54

Refering innerHTML of generated HTMLElement causes mXSS - a kind of DOM based XSS.

e.g, the code following causes mXSS at IE.

var s = "<listing>&lt;img src=1 onerror=alert(1)&gt;</listing>";
var parser = new DOMParser();
var doc = parser.parseFromString( s, "text/html" );
div.innerHTML = doc.body.innerHTML;

therefore, you have to manipulate as HTMLElement, don't refer innerHTML.

div.appendChild( doc.body.childNodes[ 0 ] );

see http://utf-8.jp/public/20140807/shibuyaxss.pdf and http://utf-8.jp/public/rickdom/

  • mXSS is really interesting and make you feel that html sanitize is a sad mess to deal with :) I guess server side sanitize is the only "sane" way but still really really hard and a never ending battle. Sep 8, 2014 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.