66760
**質問**  
HTMLエスケープはどういう時に必要ですか？

* * *

**質問経緯**  
・これまで、出力直前に必ずHTMLエスケープを実施してきました。ここでいうHTMLエスケープとは、PHPの htmlspecialchars
のような、htmlタグを無効化するものを想定しています  
・しかし、(HTMLエスケープ処理を)必ずしも毎回実行しなくてもよいのでは？ と思ったので質問します

* * *

**下記ケースでは、それぞれ(出力直前に)HTMLエスケープが必要ですか？**

  * a.「任意user」がフォームからPOST送信した内容を、受信後すぐにブラウザ出力
  * b.「自分」がフォームからPOST送信した内容を、受信後すぐにブラウザ出力

  * c.DBから取得した内容をブラウザ出力。※DBデータは「任意user」がフォームからPOST送信した内容

  * d.DBから取得した内容をブラウザ出力。※DBデータは「自分」がフォームからPOST送信した内容
  * e.DBから取得した内容をブラウザ出力。※DBデータはフォームを使用せずINSERTした内容
CC BY-SA 4.0
2020-05-19T02:19:30.997
66758
2020-05-20T01:04:51.160
2020-05-19T10:45:34.540
19110
7886
question
html security
HTMLエスケープについて
基本的には外部から入力されるデータは「ユーザの誰が」入力したかは関係なく、許可していない限りは出力する際にエスケープするべきです。

エスケープしている処理を入れているということはクロスサイトスクリプティングの脆弱性については理解しているという前提で記述します。もし、そのあたりが不明な場合はIPAの[安全なウェブサイトの作り方](https://www.ipa.go.jp/security/vuln/websecurity.html)  
を参考にしてください。

> a.「任意のuser」がフォームからPOST送信した内容を受信後ブラウザに出力  
>  b.「自分」がフォームからPOST送信した内容を、受信後すぐにブラウザ出力

これらは任意のユーザであれば危険で自分であれば安全かと認識される人もいますが、これは間違いです。

例えば、ログインしている人のメールアドレスを表示するページがあった時に、そのページにXSSがあったとします。  
攻撃者がそのページにXSSで相手のメールアドレスを抜き取るスクリプトを仕込み、さらにそのURLをターゲットににアクセスさせるようにリンクを作ってアクセスさせたらどうなるでしょうか？  
自分がアクセスしているとしてもそれを横から抜かれるのがXSSの特徴です。

> c.DBから取得した内容をブラウザ出力。※DBデータは「任意user」がフォームからPOST送信した内容  
>  d.DBから取得した内容をブラウザ出力。※DBデータは「自分」がフォームからPOST送信した内容

これらも「ユーザの誰が」は関係なくクロスサイトリクエストフォージェリー（CSRF）の脆弱性と合わせて、XSSで攻撃される可能性があります。  
CSRFはPOSTを偽装することで有効なリクエストとみなす攻撃なので、  
例えば住所を変更するようなページにSCRFがあったとします。とすると攻撃者がまたも適当なページで住所を変更するPOSTを投げるように仕向けます。  
そのPOSTデータを、誤って処理してしまって別のページでXSSで表示したら情報が抜かれたということが起きますね。

> e.DBから取得した内容をブラウザ出力。※DBデータはフォームを使用せずINSERTした内容

ここまでで「ユーザの誰かが」と言っていましたが、この質問に関しては「システム」が出力したデータに関しての質問なので安全性が確保できているのであれば、エスケープの必要はないでしょう。

また、「許可していない限り」とあるようにユーザにHTMLを入力してもらって、出力するようなことはシステムの仕様であり得ると思います。その場合は危険なタグを除去するなどの処理が必要になりますが、往々にして非常に難しい仕様になるのでほとんどの場合はマークアップ言語を用いて運用することが多いと思います。

あくまで脆弱性とはその言葉の通り脆く弱いところでそれだけでは実はすぐには攻撃が通ったりセキュリティ事故は起こらないものもあります。ですが、放置しておくとそれらが組み合わさって大事故が起こりえます。  
ぜひ日ごろから注意して、ウェブサイトを作ってみてください。
CC BY-SA 4.0
2020-05-19T03:33:31.730
66760
2020-05-19T03:33:31.730
22665
66758
answer
HTML エスケープが生データ→ HTML 化の際の文字実体参照変換や数値文字参照変換であるとして

> 出力直前に必ずHTMLエスケープを実施してきました

で正解でしょう（セキュリティ的にもデータの再利用性向上のためにも）

データベースに格納すべきは生データです。不要な加工をしたデータを格納すると再利用しにくくなります。そして、その生データを Web UA
にレンダーしてもらう場合には HTML エスケープが必須です。

  * `McDonald's` でも
  * `<SCRIPT>alert("XSS")</SCRIPT>` でも
  * `' OR 1=1 --` でも

脆弱性を発生させないよう正しく受け取り正しく表示させるために「＊＊の都合で△△処理が必要」と考えればどこで何が必要かは自明でしょう。

<http://kmaebashi.com/zakki/zakki0042.html>

* * *

`htmlspecialchars` が「タグを無効化する」とコメントにありますが全くの誤認で、

  * `text/plain` なデータがあるとき（末端ユーザ/管理者のどちらが入力したかを問わず)
  * `text/html` にそのデータを出力したいのであれば
  * `htmlspecialchars` を１回だけ使うのは当たり前で使わない選択肢はあり得ない

ってだけです。結果的に「タグっぽい」文字列があってもタグでなくなるだけのこと。

`TarO&JirO` という `text/plain` なデータが (DB 内に/プログラム内に) あるとき、これを Web
の向こう側にいる末端ユーザに正しく見てもらうには `text/html` に変換する必要があって、変換結果は `TarO&amp;JirO`
になるだけの話。同様 `<SCRIPT>` って文字列を正しく見てもらうには `&lt;SCRIPT&gt;` に変換する必要がある。
`htmlspecialchars` の働きはこれだけのことです。だから最初に文字実体参照への変換と限定してるわけッス。

<https://qiita.com/mpyw/items/19e6fed835ccdbcb0d6d>
CC BY-SA 4.0
2020-05-19T03:34:14.627
66762
2020-05-20T01:04:51.160
2020-05-20T01:04:51.160
8589
8589
66758
answer