|
|
[これから始める人のPHPガイド]
|
| ||
| ||
| ||
| ||
| ||
|
では,どうしてregister_globalsをOnにすると問題なのでしょう? そこで,いったんphp.iniの設定を
としてApacheのサービスを停止し,再起動してみましょう。PHPのスクリプトを実際に動かして挙動を確かめたいと思います。
リスト1(ontest.php)は,入力したパスワードが合致すれば,管理者用のプログラムを起動するHTMLフォームです(図1[拡大表示])。パスワードを入力して送信ボタンをクリックすると,postメソッドによってサーバーのontestsub.php(リスト2[拡大表示])にパスワードが送信され,パスワードが正しい場合に処理が行われるというわけです(図2[拡大表示])。パスワードが「php」であることはリスト2[拡大表示]を見ればわかりますね。
実はこのプログラム,register_globalsがOnになっていないと正しく動作しません。Onになっていると,HTMLフォームにある<input>タグのname属性に設定した名前を,そのままグローバル変数として扱えるからです。リスト1[拡大表示]の(1)でname属性がpassnoとなっていますね。これが,リスト2[拡大表示]の(1)のように$passno変数の値として呼び出せるわけです。
「便利じゃないか」――その通り。では,どうして4.2以降のバージョンではregister_globalsをデフォルトでOffにしたのでしょう。
食品に対する信頼が揺らいだことで,牛肉を買うときにはラベルを注意深く見ることが多くなりました。和牛,国産,オーストラリア産…。今日はしゃぶしゃぶだから和牛にしようとか,安全そうだからオーストラリア産にしようとか考える人もいるでしょう。でも,ラベルに産地が書いてなかったり,書いてあっても嘘だったりすると困りますよね。
実はregister_globalsがOnだと,どこから来た値(牛肉)なのかがわからないのです。ためしに,ブラウザのアドレス欄に「http://127.0.0.1/sample/ontestsub.php?passno=php」と入力して実行してみてください。なんと,図2[拡大表示]の画面が開いてしまったはずです。つまり,HTMLフォームからパスワードを入力しなくても,URLパラメータとしてパスワードを渡してしまうことで“管理者用の”プログラムを実行できてしまったわけです。HTMLフォームを経由せずに管理者用プログラムを実行できるのですから(もちろん,パスワードを事前に知っている必要がありますが),セキュリティ上問題があるのは当然ですね。そこでラベルのない(素性のはっきりしない)変数を使えなくするためにregister_globalsをOffにするようになったのです。
では,register_globalsがOffの場合には,どうやってサーバー側で入力値を受け取ればいいのでしょう。結論から言うと表1[拡大表示]の連想配列を使って,経路別に入力値を扱うことになります。先ほどの例で言うなら,リスト2[拡大表示]の(1)の部分を,
と書き換えてください(リスト3[拡大表示])。$_POST['passno']は,$_POSTに格納された値を,キーpassnoを使って取り出すという意味です。ラベル(postメソッドで送信された値であるという素性)がはっきりしていますね。
register_globalsの設定を再びOffにしてApacheを再起動し,リスト1を実行してみましょう。前述のようなURLを入力されても大丈夫なことが確認できると思います。
本セミナーで取り上げているPHPはバージョンが4.2.3であるため,皆さんが自分の環境でPHPアプリケーションを開発するなら,最初からregister_globalsがOffに対応したスクリプトを書けばいいでしょう。
しかし,残念ながらPHPの世界は混沌としています。レンタル・サーバーやすでにPHPを運用しているサーバー・マシンでは,まだregister_globalsがOnのままになっているケースが少なくないのです。そんなサーバーで皆さんが作った新しいプログラムを動かすとなった場合,注意してほしいことがあります。
それは,register_globalsがOnである限り,ブラウザから送信されたグローバル変数は“生きている”という点です。リスト2[拡大表示]をリスト3[拡大表示]のように書き換えたとしても,$passnoというグローバル変数が使えなくなるわけではありません。もし,うっかりスクリプトの中で,$passnoという変数名を使ってしまうと,そこには自動的にユーザーが入力したパスワードの値が入ってしまうことになります。これは思わぬバグの原因となるでしょう。
そこで,register_globalsがOnの設定になっているサーバー用にプログラムを書く場合は,
などとunsetコマンドを使って,あらかじめグローバル変数の値を破棄しておくことを覚えておくといいでしょう。
■著者紹介 金宏和實(かねひろ・かずみ)氏
株式会社イーザー代表取締役副社長。富山県高岡市在住。