プログラム等、内部の文字エンコーディングは決めておくべき

Security 6月 22, 2006
(Last Updated On: 2006年6月22日)

あるMLでプログラム内部の文字エンコーディングは決めない事にしている、と言う意見を目にしました。プログラムを利用するシステムにより複数の文字エンコーディングがあるのでプログラム内部の文字エンコーディングを指定しない方が便利であることが理由だそうです。このような方針でも安全なプログラムは書けますが、セキュリティ上お勧めできない設計方針と思います。

2000年2月に公開されたCERTのXSS脆弱性問題の中でダイナミックページの文字エンコーディングは必ず指定する、と言う対策が書かれていますが、これと同様の理由でセキュリティ上の問題になってしまう場合があります。XSS問題としては文字エンコーディングを指定しない場合、ブラウザが文字エンコーディングを自動的に検出して表示する事になります。ブラウザが文字エンコーディングを自動検出すると、検出した文字エンコーディングによってはXSSが可能になる場合があります。

確か、昨年くらいに「文字化けしたページの文字エンコーディングを変えるとXSSが可能になる」と言うことでページの文字エンコーディングを変えると意図しないJavaScriptが実行される危険性が指摘されていました。こちらは文字エンコーディングの自動認識ではなく、ユーザが明示的に文字エンコーディングを切り替える事により発生する問題ですが、文字エンコーディングの妥当性を確認していれば防げる問題の一つです。

プログラム等の文字エンコーディングを指定しない場合、複数の文字エンコーディングを含むおかしな文字列を作ってしまうリスクがかなり高くなります。おかしな文字列がプログラム内部にもありえる事を前提にコードを書くとなると、必要以上に文字エンコーディングの妥当性をチェックしないと、コードの安全性を担保できなくなります。

同様にデータベースの場合にも文字エンコーディングを指定せずに複数の文字エンコーディングを含むデータを保存している場合があります。このような運用も文字エンコーディングに関連する脆弱性を発生させやすくなる原因になります。

互換性がある文字エンコーディングでも表現できる文字が異なるので困る場合があります。例えば、UTF-8とUTF-16ではUTF-8で表現できる文字はUTF-16よりかなり多いです。(注:実際にはUTF-16でも確か200万ほどのコードポイントを表現できるので、現状で困ることはほとんどないです。実際にはSJISを使っていて困る、などの場合が多いと思います。)

セキュリティ的にはシステム内部で利用する文字エンコーディングを指定しない場合と指定する場合を比べると、文字エンコーディングが指定されている方がはるかにコードが分かりやすく安全性も高くなると思います。プログラム等、内部の文字エンコーディングは指定できるシステムの場合、必ず文字エンコーディングは決定しておくべきと考えています。システムによっては内部で使用する文字エンコーディングは決め打ちでUnicodeを採用しています。

PHPはプログラム内部の文字エンコーディングを指定できます。デフォルトはISO-8859-1になっていてHTTP入力、スクリプトの文字エンコーディングを内部エンコーディングに自動的に変換する場合に利用されます。PHP6に備える意味からもUTF-8を内部エンコーディングに設定するのが良いかと思います。

投稿者: yohgaki