
DOMPurify v3.4.13
DOMPurify - HTML、MathML、SVG向けのDOM専用・超高速・超寛容なXSSサニタイザーです。DOMPurifyは安全なデフォルト設定で動作しますが、多くの設定オプションとフックを提供します。デモ:
DOMPurify
DOMPurifyは、HTML、MathML、SVG向けの、DOMのみで動作する超高速かつ非常に寛容なXSSサニタイザーです。
使い始めるのも非常に簡単です。DOMPurifyは2014年2月に開発が始まり、現在ではバージョンv3.4.17に達しています。
DOMPurifyはJavaScriptとして動作し、すべてのモダンブラウザ(Safari (10+)、Opera (15+)、Edge、Firefox、Chrome、およびBlink、Gecko、WebKitを使用するほぼすべてのもの)で動作します。MSIEやその他のレガシーブラウザでも壊れることはありません。単に何もしないだけです。
MSIEをサポートする最新バージョンはDOMPurify v2.5.9であることに注意してください。MSIEと互換性のある重要なセキュリティアップデートについては、2.xブランチを使用してください。
自動テストは、プッシュのたびに現在のエンジン(Ubuntu、macOS、Windows上のChromium、Firefox、WebKit)における9つのブラウザ/OSの組み合わせをカバーしており、さらに別のマトリックスで古いエンジンのスナップショット(おおよそChromium 110、Firefox 108、WebKit 16.4まで、約3年前のもの)でスイートを再実行するため、古いブラウザでのリグレッションも捕捉されます。また、jsdom上でDOMPurifyをNode.js v20、v22、v24、v25、v26で実行しています。古いNodeバージョンでも動作することは知られていますが、まあ…保証はありません。
DOMPurifyは、Web攻撃とXSSに関する豊富なバックグラウンドを持つセキュリティの専門家によって書かれています。恐れることはありません。詳細については、セキュリティ目標と脅威モデルもお読みください。ぜひ読んでください。本当に。そして、生々しい詳細を楽しみたい方には、攻撃クラスとバイパス履歴ページで、DOMPurifyが防御するパーサーミューテーション、名前空間、クロバリング、テンプレートのトリックがカタログ化されています。
DOMPurifyプロジェクトは、HTML Sanitizer APIの作成にインスピレーションを与えました。これはすでに多くのブラウザで出荷されています。同じ機能は現在、WHATWG HTML仕様で直接標準化されつつあります。
目次
- 何をするのか?
- 使い方は?
- デモはありますか?
- セキュリティ バグを見つけた場合は?
- サンプルの浄化例をいくつか見せてもらえますか?
- 何がサポートされていますか?
- Internet Explorer のようなレガシーブラウザはどうですか?
- DOMPurify と Trusted Types はどうですか?
- DOMPurify を設定できますか?
- 永続的な設定
- フック
- 削除された設定
- 継続的インテグレーション
- セキュリティメーリングリスト
- 誰が貢献しましたか?
何をするのか?
DOMPurify は HTML をサニタイズし、XSS 攻撃を防ぎます。DOMPurify には、たとえば危険な HTML でいっぱいの文字列を渡すことができ、クリーンな HTML を含む文字列を返します(別途設定しない限り)。DOMPurify は危険な HTML を含むすべてのものを取り除き、それによって XSS 攻撃やその他の厄介な問題を防ぎます。また、非常に高速です。ブラウザが提供する技術を利用して、それらを XSS フィルターに変えます。ブラウザが速ければ速いほど、DOMPurify も速くなります。
使い方は?
簡単です。DOMPurify をあなたのウェブサイトに含めるだけです。
圧縮されていないバージョンを使用する(source-map が利用可能)
<script type="text/javascript" src="dist/purify.js"></script>
圧縮およびテスト済みの本番バージョンを使用する(source-map 利用可能)
<script type="text/javascript" src="dist/purify.min.js"></script>
その後、次のコードを実行して文字列をサニタイズできます:
const clean = DOMPurify.sanitize(dirty);
あるいは、Angular などでの作業が好きな方にはこちらかもしれません:
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize('<b>hello there</b>');
生成された HTML は、innerHTML を使って DOM 要素に書き込むことも、document.write() を使って DOM に書き込むこともできます。それは完全にあなた次第です。
デフォルトでは、HTML、SVG および MathML を許可していることに注意してください。HTML のみが必要な場合(これは非常によくあるユースケースかもしれません)は、次のように簡単に設定できます:
const clean = DOMPurify.sanitize(dirty, { USE_PROFILES: { html: true } });
何か落とし穴の可能性はありますか?
注意していただきたいのは、まず HTML をサニタイズし、その_後に_変更を加えると、サニタイズの効果を無効化してしまいやすいということです。サニタイズ済みのマークアップをサニタイズ_後に_別のライブラリへ渡す場合は、そのライブラリが独自に HTML をいじらないことを必ず確認してください。安全な利用方法や、よく考えてから使うべきタグ・属性については Security Goals & Threat Model を、後処理やマークアップのコンテキスト変更がなぜサニタイズを無効化するのかについては Attack Classes & Bypass History を参照してください。
文字列ではなく DOM ノードを渡す場合はどうですか?
DOMPurify.sanitize() は DOM ノード(Element、DocumentFragment、Document)も受け付けます。バージョン 3.4.14 以降、この経路は HTML パーサーから出力されたものではないノードに対して堅牢化されています。DOM API で構築されたノードや、XML/XHTML としてパースされたノード(たとえば DOMParser を application/xhtml+xml で使い、importNode() を併用した場合など)は、ONERROR のような大文字小文字を保持した属性名を持っていたり、<style> のような rawtext 要素が子要素や自身の終了タグをテキスト内に含んでいたりする可能性があります。どちらの形も HTML パーサーでは決して構築できないため文字列サニタイザーには見えませんが、再パース時に抜け出してしまいます。DOMPurify は現在、属性を正確な Attr ノード単位で削除し、こうしたリテラルテキストのツリーを安全でないものとして扱うため、入力側でのドキュメントコンテキストの混在はカバーされています。_出力_側でコンテキストを混在させないことは引き続き利用者の責任です。上記の段落を参照してください。
なるほど、では次に進みましょう
マークアップをサニタイズした後は、プロパティ DOMPurify.removed を確認して、どの要素や属性が取り除かれたかを調べることもできます。このプロパティをセキュリティ上重要な判断に使用しないでください。これは好奇心旺盛な方のためのちょっとした補助にすぎません。
サーバー上で DOMPurify を実行する
DOMPurify は技術的には Node.js を使ったサーバーサイドでも動作します。私たちのサポートは Node.js のリリースサイクルに従うよう努めています。
サーバー上で DOMPurify を実行するには DOM が存在する必要があり、これはおそらく驚くことではないでしょう。通常は jsdom が選択肢となり、jsdom の最新バージョンを使用することを強く推奨します。
なぜか? なぜなら、古いバージョンの jsdom には、DOMPurify が 100% 正しく動作していても XSS を引き起こすようなバグがあることが知られているからです。たとえば jsdom v19.0.0 には既知の攻撃ベクターがあり、jsdom v20.0.0 で修正されています。そのため、jsdom を最新の状態に保つことを本当に推奨します。
また、happy-dom のようなツールも存在しますが、現時点では安全とは見なされていません。DOMPurify と happy-dom の組み合わせは現在推奨されておらず、XSS につながる可能性が高いです。選択したサーバーサイド DOM がなぜ信頼できるコンピューティングベースの一部となるのか、その背景については Attack Classes & Bypass History を参照してください。
Cloudflare Workers や Vercel Edge など jsdom が動作しないランタイムでは、purify-edge が parse5 ベースの window 上で未改変の DOMPurify を実行するサードパーティプロジェクトです。私たちのテストスイートは互換性チェックとして npm run test:purify-edge でこれに対して実行できます。これは私たちが保守しているものではなく、テストが通ったからといって推奨やセキュリティ保証を意味するものではありません。
それ以外については、サーバー上で DOMPurify を使用して問題ありません。おそらく。これは本当に jsdom やサーバーサイドで利用する DOM に依存します。それを受け入れられるなら、動作させる方法は次のとおりです:
npm install dompurify
npm install jsdom
jsdom(最新バージョンを使用してください)の場合、これでうまくいくはずです:
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
const clean = DOMPurify.sanitize('<b>hello there</b>');
インポートを使って作業したい場合は、次のようにもできます:
import { JSDOM } from 'jsdom';
import DOMPurify from 'dompurify';
const window = new JSDOM('').window;
const purify = DOMPurify(window);
const clean = purify.sanitize('<b>hello there</b>');