CORB Leaks
October 1, 2020
Cross-Origin Read Blocking (CORB) は、Spectre などの投機的サイドチャネル攻撃の影響を軽減することを目的とした、Web プラットフォームのセキュリティ機能です。残念ながら、特定のタイプのリクエストをブロックすることで、あるリクエストではCORBが実行され、別のリクエストでは実行されなかったことを攻撃者が検出できる、新しいタイプのXS-Leaks 1 をもたらしました。とはいえ、このXS-Leaksは、CORBによって積極的に保護される問題(Spectreなど)よりもはるかに影響は少ないです。
info
これはChromiumの既知の問題であり、未修正のままであるかもしれませんが、ChromiumベースのブラウザでデフォルトでSameSite Cookieが展開されることにより、その影響は大きく軽減されます。
CORB & Error Events #
攻撃者は、CORBがレスポンスからボディとヘッダーを取り除く結果となるステータス コード2xxで、レスポンスがCORB protectedContent-Type(およびnosniff)を返す場合、CORBの保護機能が強制的に実行されたことを観察することができます。この保護機能を検出すると、攻撃者はステータスコード (成功 もしくは エラー) と Content-Type (CORBで保護されているかどうか) の両方の組み合わせをリークさせることができます。これにより、以下の例に示すように、2つの可能な状態を区別することができます。
- 1番目の状態はリクエストがCORBによって保護され、2番目の状態では、クライアントエラー(404)となる。
- 1番目の状態はCORBによって保護され、2番目の状態では保護されない。
以下の手順で、最初の例の文脈でこの保護機能を悪用することができます。
- 攻撃者は、
Content-Typeがtext/htmlでnosniffヘッダーが設定された200 OKのレスポンスを返すリソースをscriptタグに、クロスオリジンリソースとして埋め込むこみます。 - 機密性の高いコンテンツが攻撃者のプロセスに入るのを防ぐため、CORBは元のレスポンスを空のレスポンスに置き換えます。
- 空のレスポンスは有効なJavaScriptであるため、
onerrorイベントは発生せず、onloadが代わりに発生します。 - 攻撃者は、1.と同様に2番目のリクエスト(2番目の状態に対応)をトリガーし、
200 OK以外のものを返します。このとき、onerrorイベントが発生します。
興味深い動作は、CORBがリクエストから有効なリソースを作成し、JavaScript以外を含む可能性がある(エラーを引き起こす)ことです。非CORB環境を考慮すると、1.と 4.の両方のリクエストがエラーを引き起こします。これは、これらの状況によって区別可能であるとしてXS-Leakを導入しています。
nosniffヘッダーの検出
#
CORBは、リクエストに nosniff ヘッダーが存在する場合、攻撃者に検出されてしまう可能性があります。この問題は、CORBがこのヘッダーの存在と一部のスニッフィングアルゴリズムによってのみ強制的に実行されることに起因しています。以下の例では、2つの区別可能な状態を示しています。
- CORBは、リソースが
nosniffヘッダーと共にContent-Typeがtext/htmlで提供される場合、scriptとして認識されたリソースを埋め込んだ攻撃者ページを防止します。 - リソースが
nosniffを設定せず、CORBがページのContent-Typeを推測できない場合(text/htmlのまま)、コンテンツが有効なJavaScriptとして解析できないためSyntaxErrorが発生します。このエラーは、scriptタグが特定の条件下でのみエラーイベントをトリガーするため、window.onerrorをリッスンすることで捕捉できます。
対策 #
| SameSite Cookies (Lax) | COOP | Framing Protections | Isolation Policies |
|---|---|---|---|
| ✔️ | ❌ | ❌ | RIP 🔗 NIP |
🔗 – 異なるシナリオに対して有効な防御機構を組み合わせる必要があります。
tip
開発者は、アプリケーションのサブリソースにCORPを展開し、いつ動作するかを決定するためにレスポンスを検査しないCORBと同様の保護を強制することができます。攻撃者がこのXS-Leakを悪用するのを防ぐために、一般的なXS-Leakの防御メカニズムも有効です。