HTML実体参照エンコーダー/デコーダー

HTML特殊文字を実体参照にエンコード・デコード

テキストHTMLエンティティ

HTML実体参照エンコーダー/デコーダーについて

エンコードでは& < > " 'の5文字を&amp; &lt; &gt; &quot; &#39;に、©・€・—などよく使う記号22種を名前付き実体参照に、それ以外のASCII外の文字(かな・漢字・絵文字など)を&#12354;のような10進数値参照に変換します。デコードはブラウザと同じ規則に従い、HTML標準の名前2,125個すべてと10進・16進の数値参照を元に戻します。表にない名前はそのまま残します。

実体参照を使う理由は2つあります。HTMLの構文文字(<や&)を文字として表示するため、そしてユーザー入力がタグやスクリプトとして解釈されないようにするためです。後者はセキュリティの問題なので、どの文字をどこで変換すべきかを正確に知っておく必要があります。

XSS対策で本当に重要な文字

OWASPのXSS対策ガイドは、出力する場所(コンテキスト)ごとに必要な処理が違うと説明しています。タグの間の本文なら<と&を変換すれば新しいタグは開きません。引用符で囲んだ属性値の中なら、その引用符と&が要です。引用符を変換し忘れると、値を閉じてonmouseover=...のような属性を追加されます。このツールは5文字すべてを変換するので、本文と引用符付き属性の両方で安全な出力になります。

一方、実体参照では防げない場所があります。

  • 引用符なしの属性値:<div class=値>では空白や/、=でも値が終わります。属性は必ず引用符で囲んでください。
  • <script>と<style>の中:これらは実体参照を解釈しない生テキスト要素で、&lt;は4文字のまま残ります。防ぐべきは</script>という文字列で、JSONで直列化して<を\u003cにします。
  • hrefやsrcのURL:javascript:alert(1)には変換対象の文字がありません。しかも属性値の実体参照はブラウザが先に展開するので、javascript&#58;と隠しても実行されます。https:などの許可スキームかを別途検証します。

&#39;と&apos;

アポストロフィを&#39;で書くのは歴史的な理由です。&apos;はXMLには最初からありましたが、HTML 4にはなく古いブラウザが認識しませんでした。現在のWHATWG HTML標準には&apos;があるので両方使えますが、HTMLメールなど古いレンダラーを通る可能性があるなら&#39;が無難です。

デコードがブラウザの規則に従う部分

HTML標準の名前付き文字参照は2,125個あり、&amp、&lt、&copy、&yenなど106個は互換性のためセミコロンなしでも展開されます。このツールも同じ表を使うので、&hearts;や&yen;、セミコロンなしの&copyも元に戻ります。セミコロンがないときは表にある最長の古い名前だけを置き換えるので、&notit;は¬it;になります。ただし属性値の中では、ブラウザは&copy=のように後ろに=や英数字が続く場合は展開しません。このツールは常に本文テキストの規則で展開します。

数値参照も標準どおりです。&#128;〜&#159;はWindows-1252の文字に読み替えるので、&#150;は–(U+2013)、&#146;は’になります。&#0;、単独のサロゲート値(&#xD800;)、U+10FFFFを超える値はU+FFFDになります。数値参照の後ろのセミコロンもブラウザと同じく省略できます。

&amp;amp;が見えたら二重エンコード

掲示板のタイトルに「Tom &amp; Jerry」がそのまま出たり、保存のたびにamp;が増えたりするのは、エンコードを2回しているからです。保存時に一度変換し、自動エスケープするテンプレートがもう一度変換している、というのが典型です。原則は「保存は原文、出力時に一度だけ」。すでに壊れたデータは、このツールでデコードを繰り返して変化しなくなるまで戻せば中身を確認できます。

日本語を数値参照にする必要はあるか

ページがUTF-8で配信されていれば不要です。「あ」はUTF-8で3バイトですが、&#12354;は8バイトになりファイルが大きくなるだけです。文字コードを管理できない場所にHTML断片を渡すときくらいしか出番はありません。

例

コメント欄の入力を安全に表示

入力
<img src=x onerror=alert(1)>
結果
&lt;img src=x onerror=alert(1)&gt;

<が変換されるのでタグは開かず、文字として表示されます。本文コンテキストならこれで十分です。

属性値から抜け出す試み

入力
" onfocus="alert(1)
結果
&quot; onfocus=&quot;alert(1)

value="..."の中に入れても引用符が閉じません。属性を引用符で囲んでいる場合に限ります。

かなと記号

入力
あ © 2026 — ¥500
結果
&#12354; &copy; 2026 &mdash; &yen;500

あ(U+3042)は10進12354。©、—、¥は名前付きに変換されます。

使い方

  1. テキストを貼り付けます。
  2. エンコードかデコードを選びます。
  3. 結果をコピーしてHTMLやコードに入れます。

よくある質問

これだけでXSSは防げますか?

タグ間の本文と引用符付き属性値なら十分です。scriptブロック、URL属性、引用符なし属性、CSSは別の処理が必要です。自動エスケープのテンプレートとtextContentを使うのが基本です。

&nbsp;は普通のスペースと何が違う?

U+00A0で、そこで改行せず、連続しても詰められません。コピーすると通常のスペースではないため、検索や比較がずれることがあります。

セミコロンのない&heartsが展開されません。

セミコロンなしで展開されるのはHTML標準が定めた古い名前106個(&amp、&copy、&yenなど)だけで、&heartsは含まれません。ブラウザもそのまま残します。&hearts;と書いてください。

10進と16進はどちらを使う?

結果は同じです。U+表記と対応させやすい16進がよく使われます。このツールのエンコードは10進です。

関連ガイド

出典

基準日:

プライバシーとデータの扱い