PHPの変更点で最も議論の対象となったのは、おそらく、PHP 4.2.0において PHPのディレクティブ register_globalsが デフォルトでONからOFFに変更された時でしょう。 当時、このディレクティブに依存することが一般的であり、多くの人は、 このパラメータの存在すら知らず、PHPの動作そのものであるというよう に考えていました。このページは、このディレクティブにより安全でな いコードを書く可能性があるということをこのページで説明しますが、 このディレクティブそのものが安全でないわけではなく、これを誤って使 用することが安全でないということを念頭においていてください。
register_globalsをonとした場合、この機能により、HTMLフォームから投 稿される変数と同時に、あらゆる種類の変数がスクリプトに注入される ことになります。これは、PHPにおいては変数の初期化が不 要であるということにも関係し、安全でないコードを書くことが極めて容 易になるということを意味します。困難な変更でしたが、PHPコミュニティ は、このディレクティブをデフォルトで無効とすることを決定しました。 onとした場合、どこから来たのかが不明であり、出処を仮定するしかない 変数を使用することになります。スクリプト自体で定義される内部変数は、 ユーザにより送信されたリクエストデータと混ざってしまいますが、 register_globals を無効とすることでこれを回避することができます。 以下にregister_globalsの誤った使用例を示しましょう。
register_globals = onとした場合、上記のロジックは破綻する可能性が
あります。offの場合、$authorized
はリクエストに
より設定することはできず、正しく動作します。しかし、一般に良いプロ
グラミング法は、変数を最初に初期化することです。例えば、上の例で
$authorized = falseを先頭に置いておくことができ
ます。これにより、ユーザはデフォルトで認証されない状態となるため、
register_globalsのon/offによらず上記のコードは動作します。
別の例は、 セッションに関するも
のです。register_globals = onとした場合、以下の例で
$username
を使用することもできますが、
(URLにより)GETのような他の手段によっても
$username
を設定することができることに留意する
必要があります。
偽造が試みられた時に警告するために予防的な計測を行うことも可能です。
ある変数の出処を前もって正確に知っている場合、
投稿されたデータが適切な投稿元からのものであるかを調べることができ
ます。これは、データが偽造されたものでないことを保証するわけではあ
りませんが、攻撃者による偽造の成立を限定的なものにすることができま
す。リクエストデータの出処を気にかけない場合、
$_REQUEST
を使用することができます。
この変数には、GET、POST、COOKIEが合わさって含まれています。
本マニュアルの
PHPの外部変数の
セクションを参照してください。
例 29-3. 簡単に変数汚染を検出する
|
もちろん、register_globalsをoffにするだけでは、使用するコードが安 全であることを意味しません。投稿された全てのデータ毎に 他の手段で検証することも必要です。ユーザデータを常に検証し、 使用する変数を初期化してください! 初期化されていない変数を調べるには、 error_reporting()で E_NOTICEレベルのエラーを有効にするように してください。
register_globalsをOnまたはOffのエミュレートに関数情報に ついては、FAQを 参照してください。
スーパーグローバル: 使用可能なバージョンに関する注意: PHP 4.1.0 以降、
$_GET
,$_POST
,$_SERVER
等のスーパーグローバル配列が使用可能となっています。 詳細な情報については、マニュアルの superglobals のセクションを参照してください。