web-dev-qa-db-ja.com

createHTMLDocumentを使用してHTMLをサニタイズすることは安全ですか?

hTMLサニタイズを行うためにcreateHTMLDocumentを使用するのがどれほど安全か疑問に思っています。私はそれを次のように実装しようとしました:

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;
  Elm.appendChild(cleaned_fragment);

  return Elm.innerHTML;
}

私が投げたすべてのXSS攻撃で問題なく動作するようです(スクリプトの評価や要求のトリガーはありません)。しかし、私はそれが悪い考えかもしれないと感じました、私は何かを逃しているのですか?

誰かが実験したい場合はjsfiddle を作成しました。

7
Mattias Wadman

DOMParser を使用してHTMLを解析します(利用可能な場合)。前者が利用できない場合にのみ、DOMImplementation.createHTMLDocumentにフォールバックします。

Opera Prestoで、<img src=...><video>ではなく)を渡したときにネットワークアクティビティを観察しました。
Internet Explorer 9-はさらに悪い:メディア、スタイル、イベントリスナーはこのメソッドでアクティブ化されます。 IE10 +はDOMParserをサポートしているため、視聴者がIE10 +を使用している場合は安全です。

6
Rob W

生成されたHTMLElementのinnerHTMLを参照すると、mXSS(DOMベースのXSSの一種)が発生します。

たとえば、次のコードはIEでmXSSを引き起こします。

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;

したがって、HTMLElementとして操作する必要があります。innerHTMLを参照しないでください。

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

http://utf-8.jp/public/20140807/shibuyaxss.pdf および http://utf-8.jp/public/rickdom/ を参照

2
HASEGAWA Yosuke