| « Sendmail脆弱性の攻撃コード | Sendmailにセキュリティホール » |
htmlspecialchars/htmlentitiesの正しい使い方
Link: http://blog.ohgaki.net/index.php/yohgaki/2006/02/28/php_selfa_ma_a_ra_fa_fa_oa_a_sa_a_oa#c849
htmspecialchars($str, ENT_QUOTES);
じゃなくて、
htmspecialchars($str);
で終わらせてしまった場合の、
問題例が非常に欲しいです!!
とコメントを頂きました。
htmlspecialcharsとhtmlenties関数はENT_QUOTESを指定しないとENT_COMPAT(セキュリティ上問題があるが互換性を維持)が指定された状態と同じ動作をします。
ENT_QUOTESは"と'の両方をHTMLエンティティに変換するオプションです。ENT_COMPATは"のみHTMLエンティティに変換します。
JavaScript/HTMLの文字列は"と'の両方を利用できるので
<img src='foo.img' width='<php echo htmlentities($width) >' />
と記述する事もできます。万が一、$widthに
300' style='xss:expression(bad_javascript_here)
の様な値が設定されてしまうと
<img src='foo.img' width='300' style='xss:expression(bad_javascript_here)' />
となりJavaScriptが実行されてしまいます。ENT_QUOTESを指定してればこのような場合でもJavaScriptは実行されません。
ENT_COMPATのオプション名からも分かるように、最初の実装では'をエンティティ変換しない危険性を知らなかったため"のみをエンティティ変換(エスケープ)するように実装してしまった、と思われます。本来はENT_QUOTESがデフォルトであるべきと思いますが、歴史的な経緯でENT_COMPATがデフォルトになっています。HTMLはXMLで定義されたXHTMLになっているので問題は少なくなってきていますが、いつかはENT_QUOTESをデフォルトにした方がよいかも知れません。
不正な文字エンコーディングを利用した攻撃を防ぐためにも3つ目の引数も指定する方が良いです。正しい(安全な)htmlspecialchars/htmlentiesの使い方は
htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
等とするべきです。Webアプリセキュリティ対策入門にも同様の解説を書いていると思います。(書いていないかな?)
現在の標準からするとHTMLの属性は"で囲むべきですが、過去の経緯もあって"でも'でも使えるようになっているので不用意に'で属性を囲み、htmlspecialchars/htmlentitiesをENT_QUOTESオプション無しで使うとXSSに脆弱になります。
HTMLの属性のみでなくPHPスクリプトからJavaScriptの変数に文字列を渡す場合に'を使い、htmlspecialcharsをオプション無しで使ってもXSSに脆弱になります。
<script>
var some_var = '<?php echo htmlspecialchars($str)>';
</script>
PHPのフレームワークの中にはENT_QUOTESオプションを付けていないフレームワークもあります。その場合、フレームワークの利用者は'を利用して文字列の定義するとXSSに脆弱になる可能性があるので注意が必用です。
参考になれば幸いです。