セッションポイズニング

**セッションポイズニング**（Session poisoning、別名：「**セッションデータ汚染**（session data pollution）」、「**セッション改変**（session modification）」）は、サーバーアプリケーション内の不十分な入力検証を悪用する手法である。通常、この種のエクスプロイトに対して脆弱なサーバーアプリケーションは、ユーザー入力をセッション変数にコピーしてしまう。セッション情報をクッキーに保存している場合、クッキーポイズニング（Cookie Poisoning）とも呼ばれる。

この脆弱性の根本は、状態管理の問題に起因する。それは、共有状態、競合状態、使用上の曖昧さ、あるいは状態値に対する保護されていない単純な変更などである。

セッションポイズニングは、悪意のない異なるアプリケーション（スクリプト）が同じセッション状態を共有しているものの、使用方法が異なるため曖昧さや競合状態を引き起こすようなサーバー環境において実証されている。

また、攻撃者と被害者がウェブホストを共有している場合（共用レンタルサーバーなど）のように、攻撃者がサーバー環境内に悪意のあるスクリプトを配置できるようなシナリオでも実証されている。

## 起源
セッションポイズニングは、セキュリティメーリングリストである「Full Disclosure」において、未知の新しい脆弱性として初めて議論された。2006年1月、Alla Bezroutchkoは「Webアプリケーションにおけるセッションデータ汚染の脆弱性」が新しい問題なのかと問いかけた。しかし、これは以前に他者によって指摘されていた既知の脆弱性であった。Yvan Boilyは「これは既知の状態管理の問題である」とし、/someoneは「これは新しいものではない」と述べている。

これらの脆弱性の初期の例は、Bugtraqなどの主要なセキュリティリソースやアーカイブで見つけることができる。

* 2001年7月、reverseonline.comのIsmael Peinado PalomoによるMambo Site Serverバージョン3.0.Xの深刻なセキュリティホール
* 2005年9月、unknown（uw-team）およびadam_iによるPHPセッションの改変

セッション汚染は、2007年のPrzemek Sobstelによる「PHP Session Security」などの記事でも取り上げられている。

## 攻撃例
### 単純な攻撃シナリオ
この問題に対して脆弱なコード例は以下の通りである。
```
Session("Login") = Request("login")
Session("Username") = Request("username")
```
これは以下のような単純な攻撃の対象となる。
```
vulnerable.asp?login=YES&username=Mary
```
この問題は、以下のようなソフトウェアに存在する可能性がある。

* ユーザーがユーザー名とパスワードを `logon.asp` に送信する。
* `Mary` のパスワード確認が成功した場合、`logon.asp` は `vulnerable.asp?login=YES&username=Mary` に転送する。

問題は、`vulnerable.asp` が、ページが悪意のない方法でのみアクセスされるという仮定に基づいて設計されていることにある。スクリプトの設計方法を理解した者は誰でも、ログオンユーザーを任意に設定するHTTPリクエストを作成できてしまう。

### 同一セッション変数の曖昧な使用または二重使用の悪用
Alla Bezroutchkoは、`$_SESSION['login']` が2つの異なる目的で使用されるシナリオについて論じている。

* ログインスクリプトでは、セッション変数は「このユーザーはログオンしている」ことを格納する。
* パスワードリセットスクリプトでは、セッション変数は「このユーザーはパスワードリセットを望んでいる」ことを格納する。

リセットスクリプトを悪用してログオンユーザーを任意に変更できるという競合状態が実証された。

### 任意のセッション変数への書き込みを許可するスクリプトの悪用
Alla Bezroutchkoは、開発フォーラムで観測された、任意のセッション変数への書き込みを許可してしまう例について論じている。

最初の例は以下の通りである。
```php
$var = $_GET["something"]; 
$_SESSION["$var"] = $var2;
```
（ここで、$_GET["something"] はおそらく選択ボックスなどからの入力である）。

攻撃は以下のようになる。
```
vulnerable.php?something=SESSION_VAR_TO_POISON
```


#### php.ini: register_globals = on によって可能になるセッションポイズニング攻撃
`php.ini: register_globals = on` は、いくつかのアプリケーションでセキュリティ脆弱性を有効にすることが知られている。PHPサーバー管理者は、この機能を無効にすることが推奨される。

注：register_globals = on によって有効になるセッションポイズニングの実例は、2001年7月の記事「Serious security hole in Mambo Site Server version 3.0.X」ですでに公に実証されていた。

/someoneによる2つ目の例は以下の通りである。
```php
if ($condition1) { 
    $var = 'SOMETHING'; 
}; 
if ($condition2) { 
    $var = 'OTHER'; 
}; 
$_SESSION["$var"] = $var2;
```
これは以下の場合に脆弱である。

* 攻撃者が両方の条件をfalseにすることができる場合。
* php.iniの設定ミス（register_globals = on）があり、GPC（GET、POST、またはCOOKIE）入力によって $var のデフォルト値を制御できる場合。

攻撃は以下のようになる。
```
vulnerable.php?var=SESSION_VAR_TO_POISON
```


### 共有PHPサーバー（共有Webホスティングなど）を利用したエクスプロイト
uw-team.orgの 'unknown' は、攻撃者と被害者が同じPHPサーバーを共有しているシナリオについて論じている。

攻撃はかなり容易である。

* 攻撃者はまず被害者のページを訪れ、例としてログオンする。
* 次に攻撃者は自分のアカウントにPHPスクリプトをアップロードし、（被害者のスクリプトによって設定されたもの）の内容を表示させる。
* 攻撃者はどの変数を変更する必要があるかを判断し、この変数を設定するスクリプトをアップロードして実行する。
* 攻撃者は被害者のページを訪れ、予想されたエクスプロイトが機能したかを確認する。

この攻撃は、被害者と攻撃者が同じPHPサーバーを共有していることのみを必要とする。攻撃者にとってセッション識別子のCookieをあるCookieドメインから別のドメインへ移動させることは些細なことであるため、攻撃は被害者と攻撃者が同じ仮想ホスト名を持っていることに依存しない。

## 関連項目
* セッションハイジャック
* セッションフィクセーション

## 脚注