予約 5 文字をエンコード
Tom & Jerry <script>alert("xss")</script>Tom & Jerry <script>alert("xss")</script>
この 5 文字の置換は、信頼できないテキストを HTML 本文や属性値に入れるための最低限の処理です。エンコード後はブラウザがリテラル文字として表示し、マークアップとしてパースしません。script タグはテキストとして見えるだけで、実行されません。
すべての処理はブラウザ内で実行されます — ファイルや入力はサーバへ送信されません。
上部の Encode / Decode を切り替えてテキストを貼り付けます。Encode は HTML の予約 5 文字(`&`・`<`・`>`・`"`・`'`)をエンティティ形式(`&`・`<`・`>`・`"`・`'`)に置換します。「Encode all non-ASCII」のチェックボックスを有効にすると、印刷可能 ASCII 以外のすべてのコードポイントを数値文字参照(`&#xxxx;`)に書き換えます。プレーン ASCII のテンプレートシステムや旧来のメール処理系で役立ちます。Decode はブラウザ自身の HTML パーサを実行するため、名前付きエンティティ(`©`・`…`)、10 進数値(`©`)、16 進数値(`©`)のいずれも正しく処理します。
手で HTML をエスケープ・アンエスケープする場面で使ってください。ユーザー投稿コンテンツを静的ページに貼り込む、`<` が開きタグにならずそのまま表示される原因を追う、すでに一度エスケープ済みの保存 HTML を確認するといった場合です。React・Vue・Svelte などの現代フレームワークは補間値を自動エスケープするため、アプリケーションコードのほとんどでは手動エンコードは不要です。処理はすべてブラウザ内で完結し、いかなるデータもアップロードされません。
Tom & Jerry <script>alert("xss")</script>Tom & Jerry <script>alert("xss")</script>
この 5 文字の置換は、信頼できないテキストを HTML 本文や属性値に入れるための最低限の処理です。エンコード後はブラウザがリテラル文字として表示し、マークアップとしてパースしません。script タグはテキストとして見えるだけで、実行されません。
Árbol © 2024 — ✨ 😀
Árbol © 2024 — ✨ 😀
名前付きエンティティ、10 進数値(`☀`)、16 進数値(`✨`)はすべて一度のパスでデコードされます。BMP を超える絵文字のコードポイントは内部的にサロゲートペアを使いますが、デコード後は単一の文字として現れます。
안녕하세요, 世界! €100 💡
안녕하세요, 世界! €100 💡
下流が 7 ビット ASCII しか通さない場合(古い SMTP リレー、一部のログ転送、レガシーなテンプレートエンジンなど)に、非 ASCII の各文字を数値エンティティへ置き換えます。現代の UTF-8 環境では不要で、出力サイズが大きくなり、読みづらくなります。
`'` は XML と HTML5 にはありますが、HTML 4 にはありません。古いブラウザ(スクレイパーやフィードリーダーに残るレガシーパーサを含む)は `'` をデコードせずリテラルで表示することがあります。数値形 `'` はどこでも動くため、未知のレンダリング経路を通る可能性のあるコンテンツにはより安全な既定値です。
HTML 本文コンテキストにおいてのみです。各コンテキスト(HTML 本文・HTML 属性・JavaScript 文字列・CSS 値・URL)はそれぞれ専用のエンコード方式が必要で、値が `onclick=` ハンドラや `<style>` ブロックに入る場合、`<` のエスケープは何の意味も持ちません。OWASP の XSS Prevention Cheat Sheet には主要コンテキストをカバーする 7 つのルールが挙げられています。コンテキストをまたぐ可能性のある入力には、スロットごとに自動エスケープするテンプレートシステム(React・Liquid・Mustache など)を選ぶほうが安全です。
レイヤーが違うため役割も違います。HTML エンティティ(`&`)は HTML パーサがマークアップとして解釈してしまう文字をエスケープするためのもので、ドキュメント本文や属性値の内側で使います。パーセントエンコード(`%26`)は URL の構文を壊す文字をエスケープするためのもので、`href`・`src`・フォーム送信のクエリ文字列の内側で使います。`<a href>` 属性内の URL に含まれる単一の `&` は両方が同時に必要になることがあり、`https://x.com/?a=1&b=2` のように `&` で HTML パーサを満たし、デコード後にはリテラルな `&` が URL に残るようにします。
デコーダはブラウザ自身の HTML パーサを使うため、HTML5 の名前付きエンティティ全集合(2231 種、ギリシャ文字・数学演算子・装飾文字、果ては `Ą`(オゴネク付き Ą)のような変わった文字まで)を認識します。通常のページでブラウザが描画できる文字は本ツールでもデコードされます。数値形(`&#NNN;` および `&#xHH;`)は U+10FFFF までの全コードポイントをカバーします。
いいえ。` ` は U+00A0(NO-BREAK SPACE)で、その位置での改行を抑止します。多くのフォントで見た目は通常スペースと同じ幅ですが、別のコードポイントとして扱われます。例えば `"a b".split(" ").length` は 2 ですが、`"a\u00A0b".split(" ").length` は 1 になります。` ` を YAML ファイル・CSV の列・SQL クエリに貼り込むのは、見えないパースエラーの典型的な原因です。
テキストエディタや本ツール上では、デコードするとリテラル文字列 `<script>` が得られます。その文字列を `innerHTML` でライブページに挿入すると script 要素は作成されますが、実行はされません。HTML5 仕様が遅延挿入の script を除外しているためです。DOMParser と明示的な eval 相当を組み合わせれば実行できますが、まさに「簡単なデコードが簡単な実行を意味しない」ようにするため仕様がそれを阻止しているのです。
HTML エンティティは、パーサがレンダリング前に文字へ置き換えるテキスト参照です。3 つの形式があります。**名前付きエンティティ**(`&`・`©`・`…`)はニーモニックなショートカットで、HTML5 では 2231 種が定義されています(主要なギリシャ文字・数学演算子・装飾文字など)。**10 進数値エンティティ**(`©`)は Unicode コードポイントを 10 進数で参照します。**16 進数値エンティティ**(`©`)は同じものを 16 進数で参照し、名前付きエンティティの集合を超えるコードポイントに使えます。数値形式は U+10FFFF までのすべてのコードポイントを表現できるため、ブラウザが描画できる任意の文字を扱えます。
HTML 構文では 5 文字が特別な意味を持ち、リテラル文字として現れるときはエスケープが必要です。`&`(エンティティの開始)、`<`(タグの開始)、`>`(タグの終了)、`"` と `'`(属性値の区切り)です。最初の 3 つはあらゆる HTML コンテキストで予約されています。引用符は属性値内でのみ曖昧になりますが、エスケープしておくのが安全な既定です。コードサンプル内の `<` や `>` をエスケープせずに Markdown の比較表を出力しようとして壊れるのは、まさにこの理由です。
より広い話題は **コンテキスト依存出力エンコード** で、構文ではなくセキュリティの設計パターンです。出力コンテキストごとに必要なエンコードが違います。HTML 本文はエンティティ、HTML 属性は同じエンティティに引用符を加えたもの、JavaScript 文字列はバックスラッシュエスケープ(`<` を `\x3C`)、URL コンポーネントはパーセントエンコード、CSS 値はバックスラッシュ 16 進(`\3C`)です。OWASP の XSS Prevention Cheat Sheet にルールが列挙されています。実用的な指針は、スロット単位で自動エスケープするテンプレートシステム(React JSX、Liquid `{{ }}`、Go の `html/template` など)を選び、どのエンコーダを呼ぶかを開発者が判断しなくて済むようにすることです。