同一ドメイン上の別ユーザからのCookie盗難を防ぐ


同一ドメイン上に複数のユーザがいる

これでセキュリティ問題は解決です。めでたし。

           
  *     +  うそです
     n ∧_∧ n
 + (ヨ(* ´∀`)E)
      Y     Y    *

全然めでたしじゃなかった
思いっきり嘘書いてしまったのでもう少し調べてみます。

bの攻撃

/b/hoge.html
<iframe src="/a/list.php" name="iframeid" id="iframeid" onLoad="hoge();"></iframe>
<a href="#" id="href" onClick="document.body.appendChild(document.createTextNode(iframeid.document.cookie));return false;">Get cookie</a>

<script>
    function hoge(){
        // /b/上にいるが/a/のCookieが取得できる
        document.body.appendChild(document.createTextNode(iframeid.document.cookie));
        document.getElementById("href").click();

        // 本文も取れる
        console.log(document.getElementById('iframeid').contentWindow.document.body);
    }
</script>

リンク先のサイトでは手動でクリックさせていましたが、実際はクリックすら不要で、間違って画面を読み込んでしまうだけで/a/のCookieを取得することが可能です。

aの抵抗

a側には対抗策があり、/a/list.phpに

/a/list.php
    header('X-FRAME-OPTIONS: DENY');

と書いておけばフレームでのファイル読み込みを防ぐことができます。
b側にはBlocked a frameのSecurityErrorが返され、その場合bはaのCookieを読むことはできません。

aもFRAMEを使えなくなりますが、まあ今時フレームなんか使わないから問題ないでしょう。
$.ajax()等では問題なく取得可能です。

b側からフレームでのアクセスはできなくなりましたが、もちろん$.ajax()で本文を取得することは可能です。
しかし、うっかりCookieを画面上に表示していたなどという事故でもないかぎり、aのCookieは取得できません。

bの反撃

b側もこれに対応して、src="/a/image.png"とかsrc="/a/notexist.php"とか指定してきます。
画像などのX-FRAME-OPTIONSを仕込めないファイルはPHPでは対抗できません。
また存在しないファイルを指定した場合は404 Not Foundのエラーが返りますが、その場合は何故かaのCookieが読めてしまいます。

aの絶対防御

これに対抗するには、a側は.htaccessで

    Header always append X-Frame-Options DENY
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^.*$ /a/notfound.html [L]

などとしないといけません。
これによって、あらゆるファイルに常にDENYのX-Frame-Optionsがつきます。
また存在しないファイルへのアクセスはエラーページを出すことで、こちらも404 Not FoundではなくSecurityErrorを返すことができます。

逆に言うと.htaccessが設置できないサーバ、設置できてもRewriteEngineが使用できないサーバでは対抗する術がありません。

bのさらなる攻撃

とりあえずこの状態で、私が調べた限りでは/b/以下から/a/のCookieを読み取ることはできませんでした。

が、逆に考えればよいのだ。
読めなければ書き込めばいいと。

/b/set.php
    setcookie('PHPSESSID', 'evil', time()+999999, '/a/');

同一ドメインなので何の抵抗もなくCookieをセット可能です。
あとは/b/set.phpにアクセスした人がaにログインした頃合いを見計らってアクセスすれば、個人情報を取り出せるという寸法です。

まあ、これはセッション固定攻撃そのものなので、きちんとsession_regenerate_id(true)していれば特に問題ないですが。

まとめ

設定次第では、別ディレクトリからのCookie読み取りを防ぐことは可能のように見える。
何か見逃しているだけだとは思うけど。
書き込みは防げないため、勝手にログアウトされてしまったりという悪戯は可能。

とはいえ、小手先の対策を弄するより、サブドメ切ってくれるサーバに引っ越すのが一番いい。