Cache Protections
October 16, 2020
cache probingをベースとしたXS-Leakを対策するために、アプリケーションで利用できるさまざまなアプローチがあります。 これらのアプローチについて、以下のセクションで説明します。
Cache-Control
ヘッダによるキャッシュ保護
#
キャッシングを無効化することが許容できる場合には、cache probing攻撃に対する強力な対策となります。
キャッシュを無効化すると、リソースを読み込むたびに、リソースを再度フェッチする必要があります。
キャッシュを無効化するには、保護したいすべてのレスポンスに Cache-Control:no-store
ヘッダを設定します。
メリット:
- すべての主要なブラウザでサポートされている
デメリット:
- Webサイトのパフォーマンスに悪影響を与える
ランダムなトークンによるキャッシュ保護 #
キャッシュの無効化ではなく、cache probing攻撃を対策するために、アプリケーションがURLに追加のデータを含める方法もあります。 これは、参照するすべてのサブリソースのURLにランダムなトークンを含めることで実現できます。 攻撃者がこのランダムなトークンを推測できなければ、単純な手法では、攻撃者はキャッシュ内にアイテムがあるかを判断できません。
example
アプリケーションのすべてのページにユーザのプロフィール写真
/user /<USERNAME>.png
が読み込まれるとします。 攻撃者は/user/john.png
,/user/jane.png
などのキャッシュを調査することにより、どのユーザがサインインしているかを判定できます。ここでランダムなトークンが活用できます。 もし実装されていれば、アプリケーションは読み込みのたびに
/user/<USERNAME>.png?cache_buster=<RANDOM_TOKEN>
からユーザのプロフィール写真を取得します。サーバは、このランダムなトークンに対して何も行う必要はありません。 これは純粋に、攻撃者がランダムなトークンを知らないためにキャッシュを調査できないことを、実現するためだけのものとなります。
もっと丁寧に実装するのであれば、アプリケーションがページの読み込みに渡って再利用することができるユーザ固有のランダムなトークンを持つこともできます。
これにより、特定のユーザに対してURLが一定に保たれるため、サブリソースをキャッシュすることができます。
メリット:
- すべての主要なブラウザでサポートされている
- キャッシングを阻害しない
デメリット:
- 実装が難しい
Fetch Metadataによるキャッシュ保護 #
Fetch-Metadata は、クライアント側でリクエストが開始された方法と理由をサーバが判断できるようにすることを目的としています。
公開される情報の1つは、リクエストが同じオリジンからのものか、別のオリジンからのものかを指定するSec-Fetch-Site
ヘッダです。
Vary
ヘッダと組み合わせることで、リクエストが同じオリジンから行われたか、異なるオリジンから行われたかに基づいて、ブラウザにキャッシュをセグメント化させることができます。
これは、保護したいすべてのリソースに Vary: Sec-Fetch-Site
を設定することで実現できます。
example
cache probing 攻撃から保護したいリソース
cdn.example.com/image.png
があると仮定します。Vary:Sec-Fetch-Site
を設定すると、以下のように動作します。
example.com
がリソースを読み込もうとすると、リクエストは同じサイトによって開始されるため、(SFS: same-site, resource_url)
にキャッシュされます。cdn.example.com
がリソースを読み込もうとすると、リクエストは同じオリジンによって開始されるため、(SFS: same-origin, resource_url)
にキャッシュされます。evil.com
がリソースを読み込もうとすると、リクエストは別のサイトによって開始されるため、(SFS: cross-site, resource_url)
にキャッシュされます。※
Vary:Sec-Fetch-Site
をSFSと省略して記載しています。これは、クロスサイトリクエストが同一サイトおよび同一生成元のリクエストから分離されることを意味することに注意してください。
メリット:
- キャッシングを阻害しない
デメリット:
- Fetch Metadataは、新しい標準であり、現在Chromiumベースのブラウザ(ChromeやEdgeなど)でのみサポートされている
- ページに読み込まれたクロスサイトのサブリソースは保護されない(例:CDNからのサブリソース)
- サードパーティがリソースを読み込む場合には、保護されない