« 【PHPネタ】htmlspecialchars関数はサニタイズ関数? | トップページ | 【PHP関連】htmlspecialchars関数が万能でなくなるケース(2) »

2007/12/26

【PHP関連】 htmlspecialchars関数は万能で、神聖不可侵か?



昨日書きました「【PHPネタ】htmlspecialchars関数はサニタイズ関数?」の続きです。「セキュリティ云々という視点ではなく、正常系の処理をしているだけでも、大方のセキュリティ上の問題は自然とクリアできるはずなのに、『サニタイズ』という言葉をスローガンにして局所的に対応しようとするから、対策漏れが生じやすくなり、ミスが蔓延る」(上記要約は筆者がしましたので、間違っているかもしれません。各自、直接自分で読んで確かめてみてください。難しい文章ですが、何回か読んでいるととても趣旨一貫した文章だと感じられると思います。)という高木氏の主張(参照ページ)はよく理解できました(と思います)が、GIGOE氏の言う「『HTML出力と見たらhtmlspecialchars()をかける』、なんて思考停止な方法では、XSSやScript Insertionは完全には防げない」(参照ページ)という主張も、よく分かります。

まず、「思考停止」の状態かどうかは別として、単純にhtmlspecialchars関数を通すと、「鷗外」の「鷗」の字がPOSTされた際に、確認画面では「鷗」になってしまい(EUC-JPのフォームでIE7やIE6で送信した場合の話です。)期待しない結果になることは、「【PHPネタ】htmlspecialchars関数はサニタイズ関数?」でも書きました。

また、補助漢字の事例を出さなくても、EUC-JPのページで「♠♥♦♣↩❖」などの記号を入力し、IEやFirefoxでPOSTすると数値文字参照になりますから、htmlspecialcharsを通すと、やはり問題が生じます。htmlspecialchars関数でエスケープ後、再び、正規表現(preg_replace関数)で数値文字参照を元に戻してあげる処理を入れないといけないのでは? と昨日の記事で書きました。

「フォームでユーザー(サイト訪問者)が入力してPOSTしたものそのものが確認画面で表示されるのが原則。」という観点からhtmlspecialchars関数は存在しているのではないかという推論が正しいとするのであれば、この補助漢字や各種記号の処理はバグもしくは、不十分な処理と言えるのではないでしょうか? 少なくとも発展途上に見えます。

ただ、PHPがたいして難しくもないように見える、「文字実体参照」「数値文字参照」の例外処理追加を拒み?、現状htmlspecialchars関数がこのような仕様になっているのは何か理由があるのかもしれません。例えば、楽天ブログでは、EUC-JPのページですから、IEで「鷗外」と入力して投稿しようとすると、数値文字参照が生じることとなり、その結果というのか、「&# は利用できません」というエラーになり投稿できません。(Firefoxなら「鷗外」の投稿は可能ですが、そのブログを見たIEユーザーには、「乗ス外」と表示され文字化けします。Firefoxで入力した「鷗外」がIEでは「乗ス」に文字化けするからくりは、森山先生のサイトをご覧ください。)

(それなのに、楽天ブログでは、「©」の投稿はOKになっています。天下の楽天・開発陣が微妙な線引きをしていることも余計に、「数値文字参照を許可してしまうと何か起こるのではないか」と不安になります。)




単純にhtmlspecialchars関数を通すと、おかしくなる場合の別の事例。今年の2月に書いた記事:「VistaのWindows Mailプレビューで文字化けする場合(「髟阡」「瘢雹」の意味。サニタイジングについて)」で書きましたように、単純にJISコードの文字列に対して「0x3C」と「0x3E」をエスケープする処理を入れてしまうと、とんでもない文字化けが発生してしまいます。

このことは、PHPのマニュアル(htmlspecialchars)のページに掲載されていますユーザー(akira dot yoshi at shrine dot deさん)からの投稿でも触れられています。この「akira dot yoshi at shrine dot de」さんが提唱されているhtmlspecialchars_jis関数のようなものを自作するか、JISコードの文字列をEUC-JP(やUTF-8)に一旦変換した後に、htmlspecialcharsを通して、その後、再びJISコードの文字列に戻す処理をする必要があろうと思われます。


再び、htmlspecialchars関数と数値文字参照の処理の問題に話を元に戻しますが、結局のところ、数値文字参照内の「&」を「&」に戻す処理を追加してもいいかどうか、追加するとすればどのようなことに注意すべきかなどは分からないままです。htmlspecialchars関数が万能でないことは明らかですが、神聖不可侵であり、下手に触るべきでないのかどうかが分かりません。どなたかご存知の方、コメントやトラックバックを下さい。

-- 2008年1月1日14時47分ごろ追記 start --
その後、単純な正規表現で数値文字参照内の「&」を「&」に戻す処理を追加すると、まずそうな事例が見つかりました。

【PHP関連】「&」(アンパサンド)をエスケープしなければならない実例
http://shimax.cocolog-nifty.com/search/2007/
12/php_f864.html

をご参照ください。
-- 2008年1月1日14時57分ごろ追記 end --

|

« 【PHPネタ】htmlspecialchars関数はサニタイズ関数? | トップページ | 【PHP関連】htmlspecialchars関数が万能でなくなるケース(2) »

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/67411/17486530

この記事へのトラックバック一覧です: 【PHP関連】 htmlspecialchars関数は万能で、神聖不可侵か?:

« 【PHPネタ】htmlspecialchars関数はサニタイズ関数? | トップページ | 【PHP関連】htmlspecialchars関数が万能でなくなるケース(2) »