なぜPHPアプリにセキュリティホールが多いのか?

第27回 見過ごされているWebアプリケーションのバリデーションの欠陥

この記事を読むのに必要な時間:およそ 3 分

オプションモジュールのmbstring

今の所,PHP6になっても文字エンコーディングが正しい文字エンコーディングであるかチェックする関数を提供するのはmbstringモジュールです。アプリケーションで文字エンコーディングをチェックすることは,システム全体の安全性にとって非常に重要です。にも関わらず文字エンコーディングチェック関数を提供しているmbstringモジュールはオプションモジュール扱いになっています。

mbstringモジュールがデフォルトモジュールでないので,多くのPHPアプリケーションがセキュリティ維持に必須である文字エンコーディングのバリデーションコードを持たない状態が続くと考えられます。

セキュリティ面以外でも,マルチバイト圏では必須の文字エンコーディングの検出機能など,本格的なマルチバイト対応アプリケーションに必須の機能はmbstringにしかありません。

mbstringはデフォルトモジュールであったほうがWebシステム開発には都合がよいのですが,これからも必要な文字エンコーディングのチェック,特にオープンソースのアプリケーションでは,チェックが行われていないアプリケーションが多数作られると考えられます。

auto_prepend_fileの利用

PHPには幸い便利なauto_prepend_file機能があります。php.iniのauto_prepend_file設定を利用すれば,すべてのリクエストで文字エンコーディングのバリデーション処理を簡単に追加できます。この機能を利用すればアプリケーションの互換性を大きく損ねることなく,Webアプリケーションに文字エンコーディングのバリデーション機能を持たせることが可能です。

設定例:auto_prepend_file

auto_prepend_file=/path/to/validator-script.php

PHPの場合,$_GET, $_POST, $_COOKIE, $_SERVER,$_REQUEST,そして$_FILESにユーザから送信された文字列が含まれます。$_FILESのファイルデータには画像などのバイナリデータを含むと考えられるので,テキストファイルのアップロードの場合は,例外としてアップロードスクリプトで個別に処理するとよいでしょう。

$_FILESのファイルデータを除けば送信されてくる文字エンコーディングは概ね予想ができます。HTMLフォームは特に指定がなければ,ページが記述されている文字エンコーディングの文字列を送信する決まりになっています。

問題となるのは直接URLにマルチバイト文字を入力してリクエストを送信してくるユーザです。この場合,ブラウザがどの文字エンコーディングを利用してリクエスト送信してくるか予想できません。アプリケーションによってはこのようなリクエストでも正しく処理したいこともあるでしょう。その場合,送信されてきた文字エンコーディングを自動判定して文字エンコーディングをチェックするか,機械的にアプリケーションが期待する文字エンコーディングに変換してから入力文字列のエンコーディングをチェックすればよいでしょう。

前者の方法では文字エンコーディングの自動検出に成功すれば正しく処理でき,後者の場合は文字化けした文字列を使用して処理を継続できます。前者の方法を利用するメリットは攻撃用の入力を送信してきた場合に,攻撃を検出できるのでより安全性が高いと言えます。

ファイルアップロードと文字エンコーディングの自動変換

mbstringモジュールは入力文字エンコーディングを内部文字エンコーディングに自動変換する機能を持っています。この機能はファイルアップロードを行った場合は動作しないので注意が必要です。ファイルアップロードで送信されるファイルデータはバイナリであることが多いのでこのような仕様になっています。

まとめ

オープンソースのWebアプリケーションのほぼすべてがセキュリティ対策に必須といえる文字エンコーディングのバリデーション処理を行っていません。しかし,利用するアプリケーションに文字エンコーディングのバリデーション処理を追加するにはあまり多くの作業は必要ありません。

今回は文字エンコーディングのバリデーションについて解説しましたが,文字エンコーディングは厳密取り扱うことが重要です。HTTPヘッダで文字エンコーディングを指定する,データベースシステムで利用する文字エンコーディングを正しく設定する,不正な文字エンコーディングを検出した場合は絶対に処理を継続させない,などの対策も不可欠であることに留意してください。

著者プロフィール

大垣靖男(おおがきやすお)

University of Denver卒。同校にてコンピュータサイエンスとビジネスを学ぶ。株式会社シーエーシーを経て,エレクトロニック・サービス・イニシアチブ有限会社を設立。
オープンソース製品は比較的古くから利用し,Linuxは0.9xのころから利用している。オープンソースシステム開発への参加はエレクトロニック・サービス・イニシアチブ設立後から。PHPプロジェクトでは,PostgreSQLモジュールのメンテナンスを担当している。

URLhttp://blog.ohgaki.net/

著書