14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2021-07-04

[追記] 今度こそ結論。Cookieこそ盗めなくなるが、Ajaxでなんとでもできるので寄与しない

なんと著者から反応がありました。それによると、別のパスからでもXHRやFetchで自由に操作できてしまうので、Cookieを盗むまでもなく被害者の権限で攻撃ができる、ので安全性には寄与しない、とのことです。

確かによく考えるとその通りです。Cookieを盗めるか盗めないか、という点ばかりに目を取られていました。

詳しくはこちらから。

以下未修正ですのでご注意ください。


先日体系的に学ぶ 安全なWebアプリケーションの作り方を読んでいて、疑問をいだきました。

4.8.2 クッキーのセキュア属性不備の項で、CookieのPath属性について、

Path属性を指定しても、安全性が高まるわけではないことに注意してください。その理由は、JavaScriptの同一オリジンポリシーがホスト名単位であり、ディレクトリ単位ではないからです。

と書かれていたのですが、Path属性の指定が安全性に寄与しないのはなぜか、ということについて詳しい説明がありません。同一オリジンポリシーとなんの関係があるのでしょう?

気になったので調べてみました。

結論。Path属性は特殊な状況下ではある程度安全性に寄与する

Path属性は、これを設定してCookieを発行するあるパス(以下「自身のパス」)にサーバサイドのプログラムを書き換えられるような脆弱性がなく、同一オリジン内の別のパスにそのような脆弱性がある場合に、そのパスへのCookieの漏洩することを防ぐことができます。

ただし、HttpOnly属性か、HTTPヘッダにX-Frame-Option: DENYが設定されている場合に限ります。そうでない場合はXSSによって漏洩します。

そもそもPath属性はどのように安全性に寄与しそうか?

Cookieは発行時に設定されたドメインにのみ送信されます。Path属性があると、さらに設定されたパスにのみ送信されるよう、追加で制限されます。

例として、あるパス(/cart/)以下にログインフォームがあり、ログイン時にセッションIDをCookieで発行する場合、Path属性を/cart/に設定しておけば、別のパス、たとえば/items/以下からはこのCookieを参照できなくなると考えられます。

本当にそんな単純な話なのか?

単純に上記の通りに働くのであれば、「体系的に学ぶ 安全なWebアプリケーションの作り方」に、あのようには書かれていないのではないかと思います。

そのため、なんらかの落とし穴がないか調査しました。その結果、以下の2つの情報源に、Path属性が安全性に寄与しないという情報が見つかりました。

frame要素を使うと、Path属性を設定したCookieでも別のパスからJavaScriptでアクセスできる

以下のページに詳しい情報があります。frame要素でCookieを盗みたいパスを読み込むことで、parent.(frame名).document.cookie経由でPath属性が設定されているCookieをほかのパスから盗み出すことができます。

高木浩光@自宅の日記 - 共用SSLサーバの危険性が理解されていない
via CookieのDomain属性は 指定しない が一番安全 | 徳丸浩の日記

Chrome, Firefoxのそれぞれ最新版で実験しましたが、現在のブラウザでも動作するようです。同一オリジンポリシーのことを考えれば、この挙動はおそらく仕様なのでしょう。

また、「体系的に学ぶ 安全なWebアプリケーションの作り方」中で"その理由は、JavaScriptの同一オリジンポリシーがホスト名単位であり、ディレクトリ単位ではないからです。"とあった個所は、この仕様について指しているのではないかと思われます。

ただしこの仕様については、HttpOnly属性で回避できます。最近であれば、HTTPレスポンスヘッダにX-Frame-Option: DENY(当然、SAMEORIGINでは駄目)を設定することでも回避できます。

そのためPath属性を設定していても別のパスにXSSがあればCookieの漏洩を回避できないからPath属性は安全性に寄与しない、とは言えないでしょう。

Cookieの仕様であるRFC 6265がセキュリティは Path 属性に依存できないと言っている

RFCで書かれているのであれば、考慮しないわけにはいきません。以下のページには、

所与のホストの中で,パスが異なるクッキーを互いに隔離することは、一見 有用であるが,セキュリティは Path 属性に依存できない( § セキュリティの考慮点を見よ)。

とあります。

Cookies: HTTP State Management Mechanism (日本語訳)

「セキュリティの考慮点」の方を見てみますと、Path属性を使っても、およそ以下の2点については安全ではない、とのことのようです。

「8.5. 機密性の弱点」より

クッキーはパスによる隔離を常に供するものではない。 ネットワークレベルのプロトコルでは、あるパスに対応して格納されたクッキーが,別のパスに向けて送信されることはないが、一部の UA は, HTML の document.cookie API などの “非 HTTP” API を介して,クッキーを公開する。

こちらは上記の、frame要素を使ってJavaScriptからアクセスする方法も含む問題と考えられそうです。つまり、同じようにHttpOnly属性で別途回避できる問題です。

「8.6. 完全性の弱点」より

Set-Cookie ヘッダが Path 属性をサポートしていても, UA は Set-Cookie ヘッダ内の任意の Path 属性を受容するので、 Path 属性は,いかなる完全性の保護も供さない。 例えば, http://example.com/foo/bar に向けた要請に対する HTTP 応答は、 Path 属性 "/qux" のクッキーを設定できる。

こちらはCookieの発行時の話であって、セッション固定攻撃には確かにつながります。そしてPath属性ではそれを軽減できないという話で、Path属性によって漏洩を防げるかどうかについては無関係です。

ということで、"セキュリティは Path 属性に依存できない"というのは、Path属性が安全性に寄与しないという話ではなく、Path属性だけでは対応できないセキュリティの問題もある、という程度と考えてよさそうです。

結論

ここまでの調査から、以下のことがわかりました。

  1. Path属性による制限は、JavaScriptからは回避されてしまう。
  2. Path属性による制限は、セッション固定攻撃を防ぐことはできない。
  3. それ以外の場合にはPath属性による制限は有効。

3の「それ以外の場合」には、別のパスのサーバサイドのプログラムが攻撃を受けるなどして、そちらからCookieを盗み出せるような場合が含まれます。つまり、Path属性はそのような攻撃を防げると考えられそうです。

具体的にはどのような場合で有効でしょうか? 以下の2つのケースが考えられます。

  1. 別のパスだけ、サーバサイドのプログラムが書き換えられる脆弱性がある。
  2. 昔あったような、同一オリジン内で、複数の利用者がそれぞれのパスを所有している。

1については、そのようなことを考慮してPath属性による制限をつけるのは、コスト対費用的にあまり意味がなさそうです。

2については、Cookieの漏洩を考慮しなくても危険だらけのため、そのような状況で重要なアプリケーションを動かさないことがまず重要でしょう。

ということで、Path属性は安全性に寄与しないわけではないが、とはいえ考慮すべきほど意味があるとも考えられない、という結論に達しました。

つまり、「体系的に学ぶ 安全なWebアプリケーションの作り方」の記述はおそらく間違えです。

とはいえ私はセキュリティは専門ではなく、特に攻撃側には疎く、この記事に書いた以上の調査・実験もしていないため、この結論も確実とは言い切れません。詳しい情報をお持ちの方がいたら、ぜひご教示ください。

この記事のライセンス

クリエイティブ・コモンズ・ライセンス
この文書はCC BY(クリエイティブ・コモンズ表示4.0国際ライセンス)で公開します。

14
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?