Re: CookieのPath属性は本当に安全性に寄与しないのか


以下の記事を読みました。

CookieのPath属性は本当に安全性に寄与しないのか

結論として以下となっています。

結論。Path属性は特殊な状況下ではある程度安全性に寄与する
Path属性は、これを設定してCookieを発行するあるパス(以下「自身のパス」)にサーバサイドのプログラムを書き換えられるような脆弱性がなく、同一オリジン内の別のパスにそのような脆弱性がある場合に、そのパスへのCookieの漏洩することを防ぐことができます。
中略
つまり、「体系的に学ぶ 安全なWebアプリケーションの作り方」の記述はおそらく間違えです。
とはいえ私はセキュリティは専門ではなく、特に攻撃側には疎く、この記事に書いた以上の調査・実験もしていないため、この結論も確実とは言い切れません。詳しい情報をお持ちの方がいたら、ぜひご教示ください。

記事では、iframeなどを用いた攻撃について言及されていて、それに対してはX-frame-optionsヘッダやCookieのHttpOnly属性で防御できるため、Path属性により防御が可能である、としています。

確かに、現在はx-frame-optionsヘッダやCookieのHttpOnly属性をつけることが一般的ですので、もしそれで異なるパスからの攻撃が防御できるのであれば、ありがたいですね…
でも、現実には防御できないので、簡単なスクリプトを書いて検証してみました。

以下、http://example.com/ 上に2つのサイト /alice と /bob があるとします。/alice 側にはセッション管理を用いてユーザ情報を保持していて、セキュアだとします。/bob側にはXSS脆弱なページがあるとします。これは引用した部分の前提のとおりです。

以下、/alice 側のコンテンツです。まず、setuser.phpはログインシステムの代わりに、セッション変数にユーザ情報を書き込むスクリプトです。

setuser.php
<?php
  session_set_cookie_params(0, '/alice');
  session_start();
  $_SESSION['user'] = $_GET['user'];
?><body>
  ユーザがセットされました
</body>

上記の実行例です。セッションクッキーにはpath=/aliceが指定されています。

setuserした状態で下記のスクリプトを実行すると、現在のユーザ名が表示されます。

getuser.php
<?php
  session_start();
  $user = $_SESSION['user'];
?><body>
  ユーザは<?php echo htmlspecialchars($user) ?>です
</body>

実行例

続いて、/bob側の脆弱なコンテンツです。以下のスクリプトにはXSS脆弱性があります。

vul.php
<body>
サーチ文字列: <?php echo $_GET['search']; ?>
<p>以下略</p>
</body>

正常系

ここまでが準備です。攻撃者は/bob/vul.phpに対してXSS攻撃を仕掛けます。その際の攻撃用のJavaScriptは以下を用います。

fetch('/alice/getuser.php')
  .then(response => {
    return response.text()
  })
  .then(text => {
    console.log(text)
  })

ご覧のようにFetch APIを用いて、/alice/getuser.php にアクセスをして、その結果をconsoleに出力しています。この例ではFetch APIを用いましたが、XMLHttpRequestでも同様に攻撃できます。
罠サイト経由などで、これを /alice 側のログイン済みユーザ(被害者)が実行した例を示します。

http://example.com/bob/vul.php?search=%3Cscript%3Efetch(%27/alice/getuser.php%27).then(response=%3E{return+response.text()}).then(text=%3E{console.log(text)})%3C/script%3E


「ユーザaliceです」と表示されていますね。上記ではconsole.log()を用いて表示していますが、攻撃者は盗んだ情報を別のサイトに送信するなどして盗むことができます。
この際のリクエストヘッダは下記のとおりです。

Cookieが付与されてます。/alice/getuser.phpへのリクエストなので、path=/aliceと指定されたクッキーが送信されているわけです。

結論としては、XMLHttpRequestやFetch APIなどを禁止する方法はなく、仮にそのような方法があったとしてもこれらを禁止できるものではないため、クッキーのpath属性は安全性に寄与するものではないということになります。

XSSに関するYouTube動画を以前公開していますので、こちらも合わせてご覧ください。