セッションとセキュリティ
携帯端末は、PC向けのサイトでは頻繁に用いられるCookieについて、まったくサポートしていないか、サポートしていても制限のあるものが大半です(例えば、EZweb端末はCookieをサポートしていますが、保存可能な個数や文字長に制約があります)。このスクリプトでは、PHPのセッション機能を利用することで、端末の機能に関わらず、Cookieの送受信を擬似的に実現し、また、Refererの送信やアクセス履歴の表示、ベーシック認証なども可能にしていますが、この機能を利用者に提供する場合、スクリプトの管理者はセッションのセキュリティについて細心の注意を払う必要があります。
セッションファイルの管理
このスクリプトを介してリモートサイトから受信したCookieや、アクセス履歴などは、サーバ上のセッションデータに保存されます(端末がCookieをサポートしている場合でも、受信したCookieは、端末ではなくサーバに保存されます)。このスクリプトでは設置の簡易さを維持するため、これらのデータを、データベースなどではなくファイルに保存していますが、これらのファイルが決して第三者のアクセスに晒されることがないように注意してください。
セッションファイルの保存先は、設定ファイル(Config.inc.php)などで、「ini_set('session.save_path', 'ローカルパス');」のように記述することで指定します。
指定がない場合は、セッションファイルはシステムの既定のディレクトリ(例えば「/tmp」)に保存されますが、共用のサーバを利用している場合はこれは避け、自身の管理下にあるディレクトリに保存するように設定してください。この場合保存先は、HTTPなどによるアクセスが可能な公開ディレクトリ(例えばpublic_html以下)以外が利用可能であればそちらに用意してください。公開ディレクトリしか提供されていない場合は、「deny from all」のように記述した.htaccessファイルを配置するなどして、外部からのアクセスを拒絶するようにしてください。
セッション乗っ取り
このスクリプトに限らず、一般的にセッションを利用するウェブアプリケーションは、他者のセッションIDを知ることでそのセッションデータを利用可能とする、いわゆるセッション乗っ取りの危険性をはらんでいます。
PCの場合、通常はCookieに保存されるセッションIDは、携帯端末を対象としたこのスクリプトでは、 Cookieをサポートしていない端末では、URLのクエリー文字列中に埋め込まれるため、セッションIDが不用意に漏洩してしまう可能性ががあります。例えば、Refererの送信を行う端末では、このスクリプトから外部のサイトに移動した際に、そのサイトのアクセスログにセッションID を含むURLが記録されるかもしれません(そして、アクセスログを公開しているサイトは少なくありません)。あるいは利用者自身が、セッションIDを含む URLを、メールなどを通じて他者に通知してしまうことも予想されます。
このスクリプトでは、セッション乗っ取りの危険性を軽減するために、以下のような処理を行っています。
- セッションデータには、User-Agentや端末IDなど、クライアントに固有の情報を基に生成されるハッシュ値が格納されます。これは、アクセスの都度照合され、一致しない場合は、そのセッションは破棄されます。
- Session Fixation攻撃は、IDに対応するセッションデータが存在しない場合は、IDを新たに割り振り直すため無効です。また、これにより、ブックマークや画面メモなどからの利用で、同じIDが繰り返し利用されることも防いでいます。
- セッションデータには、アクセスの都度、その時刻が記録され、設定ファイル(Config.inc.php)の定数SESSION_INSECURE_LIFETIMEとSESSION_SECURE_LIFETIMEで指定する有効期限を経過しているセッションは破棄されます(PHPのGarbage Collection機構とは別途に処理されます)。
スクリプトの管理者は、これらの値を、利用者の利便を妨げない範囲で極力短く設定してください。
- 「直」リンクなど、外部サイトへの直接のリンクは、いったん中継スクリプト(r.php)を経由し、端末がRefererを送信しており、かつRefererにセッションIDが含まれる場合は、外部サイトへのリンクを表示し、RefererによるIDの漏洩を防ぎます(Refererを送信しない端末や、Cookieに対応しているなどで、セッションIDがURLには埋め込まれて露出していない端末では、そのままシームレスにリダイレクトされます)。
スクリプトの管理者は、このスクリプトのいずれかのページに、外部サイトへの直接のリンクを用意する場合は必ず中継スクリプトを経由するように、「<a href="r.php?外部サイトのURL">」のように記述してください(URLは、エンコードの有無は問いません)。
その他
リモートサイトのフォームからの送信は、通常は、POSTメソッドでこのスクリプトに送信されます(そして、あらためて本来のメソッドで、このスクリプトからリモートサイトに送信されます)。ただし、初期のJ-PHONE端末など、POSTメソッドが利用できない端末ではGETメソッドが用いられるため、全ての送信内容は、URLのクエリー文字列中に埋め込まれます。設定ファイル(Config.inc.php)で指定する、定数USE_ONLYPOST_FORPASSがtrueの場合、URLからパスワードが不用意に漏洩しないように、こうした端末ではtype属性がpasswordのINPUT要素は表示されません。
2005/08/10
トラックバック
このエントリーのトラックバックURL:
http://www.rcdtokyo.com/mt/mt-rcdtokyo5428-tb.cgi/741