HTML エンティティにエンコード

テキストを貼り付けると、文書の解析のされ方を変える文字がエスケープ形に置き換わって返ってきます。他人が書いたテキストを、構造ではなく内容にする手順であり、置き換えをひとつ忘れることがコメント欄をセキュリティの問題に変える場所でもあります。計算はこのページの中で行われます。

前者はテンプレートエンジンがすることです。後者は UTF-8 をきれいに扱えない処理の鎖のためのものです。

結果

入力すると、ここに答えが出ます。

  • 処理される場所

    ファイルがないので、何もアップロードされません。計算はこのページの中で行われます。

  • 順番待ちもアカウントもなし

    お使いの機械の速さで答え、あなたが誰かを尋ねることはありません。

  • 何度でも

    回数は数えず、上限もありません。もう一度答えることに費用はかからないからです。

仕組み

  1. テキストかマークアップの断片を貼り付けてください。
  2. どこまでエスケープするかを選びます。解析を変えるものだけか、ASCII を超えるものすべても含めるか。
  3. 結果をコピーします。端末からは出ていません。

この話のすべてである 5 文字

HTML のパーサーが気にする文字はごくわずかです。不等号の小なりと大なりがタグを開閉し、アンパサンドが文字参照を開き、属性値の中ではダブルクォートとシングルクォートが値を終わらせます。5 つで、残りはすべて普通の内容です。

だから控えめな設定はちょうどその 5 文字だけをエスケープします。すべての日本語をエンティティに変えるエンコーダーは安全度が高いわけではありません。長さが 5 倍になって人には読めなくなり、守る対象は短い版とまったく同じです。

アンパサンドが先か、さもなければ順序が壊れます

手で置き換える人は `&` から始めなければなりません。順番が後ろに来ると、エンコーダーはすでに自前のエンティティを作っており、その `&` をもう一度エスケープします。`<` が `&lt;` になり、それが `&amp;lt;` になって、ページには小なり記号ではなく `&lt;` という文字列が表示されます。

自作のエスケープ関数で群を抜いて多い失敗で、しかも出力を見れば分かる数少ない失敗のひとつです。ほかのエンティティ名の前に `&amp;` が並んでいれば順序が誤っています。このツールは 1 回の走査で置き換えるので、この問題は起こりえません。

内容と属性は同じではありません

タグとタグのあいだなら 3 つの置き換えで足ります。小なり、大なり、アンパサンド。属性値の中では引用符が加わります。そこではダブルクォートが値を終わらせ、続くものをパーサーは別の属性として読むからです。他人のタグに `onmouseover` を紛れ込ませる古典的な経路がこれです。

最悪なのは、HTML が許している引用符なしの属性値です。そこでは空白ひとつで値が終わり、エスケープだけでは足りなくなります。実務上の規則は、属性には必ず引用符を付け、5 文字をエスケープすること。このページの既定がちょうどそれです。

「ASCII を超えるものすべて」が要る場面

2 つめの設定は、ASCII の外の文字をすべて数値参照として書きます。「あ」は `&#12354;` になります。セキュリティには何も足さず、可読性には損です。処理の鎖のどこかが UTF-8 を扱えない場合にだけ意味があります。

そういう箇所はまだ存在します。古いメールのテンプレート、Shift_JIS 固定のシステムへのエクスポート、ときおり照合順序を誤った列。日本語が途中で「?」や見覚えのない記号の羅列に変わるなら、数値形は堅い迂回路です。鎖がきれいに UTF-8 を話す場所では余分です。

エスケープは出力時の衛生であって、フィルターではありません

エスケープが守るのは 1 か所、HTML に埋め込む瞬間です。入力の検証ではなく、その代わりにもなりません。表示時ではなく保存時にエスケープする人は、JSON のレスポンスや CSV のエクスポートやメールに `&amp;` が現れるデータを抱えることになります。HTML が一度も関わっていない場所でです。

うまくいく順序は逆です。生のまま保存し、描画するときに行き先ごとにエスケープする。同じデータが HTML でも JSON でもプレーンテキストのメールでも、それぞれの規則で正しく出ます。そして項目がどの状態にあるかを誰も推測せずに済みます。

同じ文字を書く 3 つの形

HTML は `&amp;` のような名前付き参照、`&#38;` のような 10 進、`&#x26;` のような 16 進を認めます。3 つとも同じ文字を指し、パーサーは 3 つとも受け付けます。このツールは決定的な 5 文字には名前付きを、それ以外には数値形を出します。名前付きはソースを読んだときに分かるからです。

他人の出力を読めば、しばしば同じファイルの中に 3 つが混ざっています。別々の部品が作ったからです。誤りでも問題の兆候でもありません。その文書に複数の道具が関わったと言っているだけです。

ここが `&#39;` で `&apos;` ではない理由

シングルクォートには `&apos;` という名前がありますが、これは XML から来たもので、HTML5 まで正式には HTML の一部ではありませんでした。HTML 4 では定義されていないので、非常に古いパーサーは解決せずそのまま出力します。

数値形の `&#39;` にはその問題が一度もなく、どこでも動くので、ほとんどのエスケープライブラリの既定であり続けています。20 年前の非互換が、理由が消えたあとも慣習を固定してしまった例のひとつです。

HTML のエスケープは JavaScript を救いません

`<script>` ブロックの中に書き出される値は、もう HTML の文脈ではなく JavaScript の文脈にあり、そこでは別の規則が効きます。エンティティとしてエスケープされた引用符は助けになりません。逆に、HTML では無害な文字列がスクリプトを閉じることがあります。

`href` や `style` や、あとで評価される `data-` 属性の中の値も同じです。それぞれに固有のエスケープがあり、正しい問いは「エスケープされているか」ではなく「行き着く場所に対してエスケープされているか」です。このツールが答えるのは HTML の場合です。

個人情報保護法から見たときの位置

この欄に貼り付けられるのは、たいてい他人のテキストです。利用者のコメント、問い合わせの本文、氏名の入った説明文。置き換えはページの中で行われるので、当方への提供が起きず、その内容についての第三者提供も委託も生じません。

ブラウザーのネットワークパネルで確認できます。使っているあいだ、入力を運ぶリクエストは出ません。ページは CDN から届き、サイトには広告があるのでリクエストはあります。あなたがここに来たことは知られ、欄の中身は知られません。

HTML エンティティにエンコード:よくある質問

テキストはサーバーへ送られますか。

いいえ。置き換えはこのページの中、お使いのブラウザーで行われます。入力しながらネットワークパネルを開けば、入力を運ぶリクエストが 1 本も出ていないのが見えます。

日本語がエスケープされないのはなぜですか。

HTML のパーサーにとっては普通の文字で、UTF-8 の文書では何も壊さないからです。処理の鎖が UTF-8 を扱えないなら、2 つめの設定を選べば数値参照として出ます。

これは XSS を防ぎますか。

HTML を組み立てるその地点では防ぎます。それが役割です。入力の検証の代わりにはならず、JavaScript や href や CSS の文脈に行き着く値には効きません。そこでは別の規則が効きます。

結果に `&amp;lt;` が出るのはなぜですか。

テキストがすでにエスケープ済みで、もう一度エスケープされたからです。ツールの不具合ではありません。処理の鎖の手前で、たいていはテンプレートエンジンのエスケープをすでに通っているという印です。

長さの上限はありますか。

お使いのブラウザーが決めるものだけです。数えたり制限したりするサーバーは存在しません。非常に大きな入力ではタブが少しのあいだ考え込みます。それだけです。

他のツール