【PHP関連】htmlspecialchars関数が万能でなくなるケース(2)
htmlspacialchars関数をそのまま単純に通すだけでは問題になる2例について、昨日の記事「【PHP関連】 htmlspecialchars関数は万能で、神聖不可侵か?」では書きました。ただ、この2例の問題ともセキュリティには関係がない話でした。
今日は、htmlspecialchars関数を通しても、場合によってはセキュリティ上、問題になるケースについて取り上げてみます。htmlspecialchars関数の責任ではないのですが、HTMLタグの書き方が悪いなど他の要因によって、htmlspecialchars関数では危険な要素を取り除くことができない場合があるということです。例えば、
1.UTF-7とXSS問題
「文字化け」を利用した攻撃。メタタグを明示していない場合に、ブラウザがそのページのエンコードをUTF-7と解釈すると、例えば、「+ADw-script+AD4-alert('hoge')+ADsAPA-/script+AD4-」という文字列がJavaScriptとして実行されるということです。「<」や「>」のような文字列は一切登場しませんが、UTF-7では、「<」を「+ADw-」のように符合することから、htmlspecialchars関数では対処しきれずに、このような問題は発生します。詳細は、下記のサイトを参照してください。
● UTF-7エンコードされたタグ文字列によるXSS脆弱性に注意
http://slashdot.jp/security/article.pl?sid=05/12/21/2318216
● www.google.comにクロスサイト・スクリプティングのぜい弱性,米Watchfireが報告
http://itpro.nikkeibp.co.jp/article/USNEWS/20051222/226650/
● 【PHP TIPS】 36. UTF-7とクロスサイト・スクリプティング
http://itpro.nikkeibp.co.jp/article/COLUMN/20070507/270087/
ただ、メタタグで文字コードがきっちり指定されていれば、ブラウザに意図的に誤認させる方法はないのか、極めて難しいのか、上記Googleの件でもメタタグで文字コードを指定することで「対策」となっているようです。
※ 結局、この問題はhtmlspecialchars関数の問題ではありません。メタタグが指定されておらず、かつ、ページ内によっぽど文字が少ないか何かで、少量のUTF-7らしき文字列が注入されている(しかも、ページソースの上部で)というような、複数の条件が重ならない限りは起こらないようです(ただ、メタタグがある場合でも、意図的に悪意のある第三者が、ブラウザに文字コードを誤認させる方法があるのかもしれませんが、それだと対策はとても難しくなりそうです)。
もちろん、他のサイト訪問者にブラウザのエンコードを変更操作するように仕向けられた場合には問題が発生しますが、今IE6 SP2(XP)やIE7(Vista)を見てみると、「UTF-7」というのはそもそも選択肢にないですね。FirefoxやOperaにはありますが・・・。FirefoxやOperaでこのページの文字エンコーディング(Operaの場合は、「エンコード」)を変更すると「hoge」と表示されるはずですが、このような誘導には乗らないようにしてください。
もちろん、他のサイト訪問者にブラウザのエンコードを変更操作するように仕向けられた場合には問題が発生しますが、今IE6 SP2(XP)やIE7(Vista)を見てみると、「UTF-7」というのはそもそも選択肢にないですね。FirefoxやOperaにはありますが・・・。FirefoxやOperaでこのページの文字エンコーディング(Operaの場合は、「エンコード」)を変更すると「hoge」と表示されるはずですが、このような誘導には乗らないようにしてください。
Googleの対策が正攻法であると感じるのは、「+ADw-」や「+AD4-」、「script」だけを取り除く(これこそ「サニタイズ」?)という方法を取らなかったことです。危険な文字列をチェックする方法を取ると、どうしても取りこぼしが生じやすくなり、脆弱性の温床になりやすいからです。
2.「"」(ダブルクォート)の重要性
下記の例で、$link_urlという変数を外部の入力に頼っている場合、
<a href=$link_url>Your homepage</a>
|
ここで「$link_url="dummy.html onClick=alert('hello');return false;";」が入ると、htmlspecialcharsを通しても危険な文字列は無効化されないため、リンクがクリックされるとJavaScriptが実行されることになります。href属性のところに「"」が入っていて、 <a href="$link_url">Your homepage</a> のようになっている場合、$link_urlの値として「dummy.html" onClick="alert('hello');return false;」を入れられたとしても、htmlspecialchars関数を通せば、$link_urlの値は、「dummy.html" onClick="alert('hello');return false;」となります。その結果、リンク先は結局、「dummy.html%22%20onClick=%22alert('hello');return%20false;」となり、結局「File Not Found」になります。 |
ですから、ダブルクォートを入れていれば問題がなかったという話であり、htmlspecialchars関数の限界というと嘘になるでしょう。
ただ、htmlspecialchars関数を通すだけだけでは安全といえないケースもあるということを知るための事例として、覚えておいて決して損はないでしょう。
PHPのプログラム内で変数の値に「"」を入っていると、「$html_output="<a href=\"$link_url\">Your homepage</a>";」などとしなければならず、この「\"」というエスケープ処理が面倒に感じてしまうことがあるのも事実です。でも、面倒くさがってはいけませんね(自戒)。
| 固定リンク
トラックバック
この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/67411/17497106
この記事へのトラックバック一覧です: 【PHP関連】htmlspecialchars関数が万能でなくなるケース(2):

コメント