セッションを使用するWebアプリケーションの安全性

最終更新日時:2008-01-09 14:58:32
Web系

セッションを使用する Web アプリケーションの安全性


はじめに


オンラインショップをはじめとする Web サービスではセッション管理を使用したものが数多く存在します。
何故セッションが必要なのか?
これは HTTP プロトコルがステートレス(状態を持たない)なプロトコルであることに原因があります。
従って、何らかの方法でアプリケーション側で状態を持つことが必要となります。
その状態を持つ手段の1つがセッションと呼ばれるものとなります。
セッションは ASP on IIS や PHP ではデフォルトで用意されてますし、Perl CGI でもモジュールが存在しており、手軽に使うことができます。
セッションを使うことにより、ユーザごとの状態(ログイン、選択した商品、入力した住所等さまざま)を引き継ぐことが可能となります。
が、便利な反面、セッションはセキュリティホールになりやすい側面も持っています。
よって、セッションを使用する際にはセキュリティ面について非常に考慮する必要があるのですが、意外と考慮されていないサイトが多く存在するようです。
個人で提供しているような遊び半分なサービスならともかく、顧客が数万以上いてしかも金銭のやりとりが発生するようなサービスでもセキュリティ面で問題があるようなサイトがけっこうあるとか。。。

セッション ID


セッションを使用するには、まずはじめにセッション ID なるものをユーザに対して発行するところから始まります。
この発行方法は、Cookie にして渡すやり方が一般的( GET パラメータにして渡すやり方や form の hidden 属性で渡す方法もある)なので、以下 Cookie にてセッション ID を渡すと仮定します。

セッション ID はユーザを一意に判別できるものなので、セッション ID が何らかの方法で入手されてしまった場合には、そのユーザに紐付く情報が全て入手されてしまう可能性があります。
そのサイトの特性によっては、住所・電話番号・名前等の個人データはもとより、クレジットカード番号のようなものまで第3者に入手されてしまうでしょう。
従って、セッション ID は決して第3者が推測可能な ID にしてはいけません。
推測できてしまった時点で、第3者が任意のユーザになりすますことが可能となってしまいます。

セッション ID が推測不可能な ID であれば第3者が正規ユーザになりすますことはかなり難しくなります。
が、推測不可能な ID でも漏洩・盗聴された場合には当然意味がありません。
そういう意味では、セッション は有効期間も可能な限り短くするべきです。
少なくとも、ユーザがブラウザを終了した際には新たにセッション ID を割り振るべきです。
実際、ASP や PHP はそのようになっています。(それプラス一定時間アクセスが無い場合に自動的にセッションが終了するようになっている)
ブラウザを起動する度に認証する必要が出てきますが、セキュリティ面を考えれば妥当なところでしょう。
こうしておけば、仮にセッション ID が漏洩・盗聴された場合でも、そのユーザがブラウザを開いている間だけセッションが有効となり、被害を受ける可能性が極めて少なくなります。
が、それでもわずかながらセキュリティホールとなる可能性(ユーザのセッションが有効な間にセッション ID を第3者が取得し、実行)は存在します。
完全にセキュリティホールとならないように対処するには、セッション ID が漏洩・盗聴されないようにするしかありません。

Cookie on SSL


セッション ID が漏洩してはどうしてもセキュリティホールになりうるので、セッション ID を盗聴されないようにすることを考えます。
物事はなかなか完全にはいかないものなので、万が一盗聴された時のためにも上記のセッション ID についての考慮も必要です。(ASP や PHP のセッションを使用しているのであればクリアしている)

セッション ID は Cookie として発行され、それ以降はユーザ側から Cookie としてセッション ID を Web サーバに渡すので、HTTP プロトコルを盗聴されてしまうとどうしてもセッション ID も盗聴されてしまいます。
従って、HTTP プロトコルを SSL で暗号化(すなわち https によるアクセス)する必要があります。
https で通信を行っていれば、通信の盗聴は不可能であることが保証されます。

secure 属性


上記のように https 通信を使用することとしても、たいていの場合まだ完全ではありません。
それは、何らかの理由でセッション ID 発行後に http 通信を行った場合には、Cookie の中身としてセッション ID が平文で流れるのでセッション ID が盗聴可能となるからです。
これを防ぐには全ページを https 対応にするだけでは不十分です。
なぜならなんらかの方法でセッション発行後に http://..:443/ のようなアクセスをするとセッション ID が盗聴可能となり、また 443 ポートは https 通信を使用する前提なので有効にせざるを得ないからです。(もっと詳しい理由はリンク先をどうぞ)

対応方法は以下のようになります。
セッション ID 発行時の Cookie を secure 属性付きで発行します。
secure 属性の Cookie は https 通信以外ではユーザ側から通知されることはありません。
従って http://..:443/ のようなアクセス時にもセッション ID を含むような Cookie は流れません。
ここまで対応して、おそらく論理的には 100% 盗聴されることはないと言えるはずです。

IIS


IIS ではデフォルトではセッション ID が盗聴可能となっています。
修正方法は SP2 以上を適用し、以下のコマンドを実行(IE5.0 の場合)すればOKのようですが、試してないし、正確な挙動も知りません(/o\)
情報を持ってる方は教えて欲しいです。

    c:\> cd %windir%\system32\inetsrv\adminsamples
    c:\> adsutil set w3svc/1/AspKeepSessionIDSecure 1


リンク


title概要
Webサイトにおけるクロスサイト スクリプティング脆弱性に関する情報 - ユーザーのセッションが奪われる可能性 -(情報処理振興事業協会 セキュリティセンター)概要はここ。
Cookie盗聴によるWebアプリケーションハイジャックの危険性とその対策(SecurIT - 産業技術総合研究所 セキュアプログラミング研究チーム)全ページ https でも不十分である理由はここ。
Cookie盗聴によるWebアプリケーションハイジャックの危険性への対応について(商務情報政策局情報セキュリティ政策室)
IIS では Cookie が SSL-Secure としてマークされないIIS での Session Cookie 盗聴の問題に対するマイクロソフトの解説
お問い合わせは 掲示板 にて。