Intel Skylake CPU で Chrome 88 を実行している場合、デモのウェブサイトでは 1 kB/ 秒のスピードでデータが漏洩する可能性があります。なお、このコードはわずかに変更するだけで他のバージョンの CPU やブラウザにも適用できると考えられます。ただし、Google のテストでは、大きな変更を加えなくても、この攻撃を Apple M1 ARM CPU などの他のいくつかのプロセッサで成功させることができました。

実験にあたり、異なる特性を持つ他の PoC も作成しました。いくつかの例を示します。
  • performance.now() を 5 マイクロ秒の精度のタイマーとして使うことで、安定性と引き替えに 8 kB/ 秒でデータを漏洩する PoC
  • 1 ミリ秒またはそれより粗い精度のタイマーを使うことで、60 B/ 秒でデータを漏洩する PoC

現在の PoC を公開することにしたのは、セットアップ時間が無視できる程度であり、SharedArrayBuffer のような高精度なタイマーがなくても動作するからです。

PoC の主な構成要素は、以下のとおりです。
  1. Spectre ガジェット : 攻撃者が制御する一時的実行を呼び出すコード
  2. サイドチャネル : 一時的実行の副作用を管理する方法

1. ガジェット

公開した PoC では、単純なバリアント 1 のガジェットを実装しました。コンパイラが挿入した長さチェックが成功することを予測する分岐予測のトレーニング後に、JavaScript 配列の境界外への投機的なアクセスが発生します。このガジェットではソフトウェア レベルの対策を取れますが、Chrome の V8 チームは、他のガジェットではそうはいかないと結論づけています。「一部の Spectre のバリアント、とりわけバリアント 4 に対しては、ソフトウェアで効果的に対策するのは不可能であるとわかりました」と述べています。

セキュリティ コミュニティの皆さんには、さらに調査をし、他の Spectre ガジェットを利用したコードを作成することをお勧めします。

2. サイドチャネル

投機的実行によって秘密データが漏洩する場合、キャッシュ サイドチャネルが使われるのが一般的です。メモリ内の特定の場所がキャッシュに存在するかどうかを管理すると、投機的実行によるメモリへのアクセスがあったかどうかを推測できます。JavaScript で難しいのは、キャッシュ アクセスとメモリ アクセスを判別できるほどの高精度タイマーを見つけることです。モダンブラウザは、タイミング攻撃を防ぐため、クロスオリジン分離が行われていない状況で performance.now() API のタイマーの精度を粗くし、SharedArrayBuffer を利用できないようにしています。

V8 チームは、2018 年時点ですでに、タイマーの精度を粗くすることは Spectre の対策としては不十分であると報告しています。攻撃者はタイミングの差を自由に増幅できるからです。ただし、そこで述べられている増幅テクニックは、秘密データを複数回読み取る方法に基づいているので、情報の漏洩が確率的なものである場合は、攻撃の効率を低下することができます。

今回の PoC では、新たなテクニックを使ってこの制限を回避しました。最近の CPU でよく使われる Tree-PLRU キャッシュ エビクション戦略の動作を悪用すれば、秘密データを 1 回読み取ることで、キャッシュのタイミングを大きく増幅することができます。これにより、低精度タイマーでも、効率よくデータを漏洩することができました。このテクニックの詳細については、https://leaky.page/plru.html のデモをご覧ください。

この PoC は、大きく改変しない限り、悪用目的で再利用できるとは考えられません。しかし、Spectre のリスクを示す上では、説得力のあるデモとなります。特に、このリスクを考慮してセキュリティ評価をする必要があるウェブ アプリケーション デベロッパーにとっての明らかなシグナルとなり、サイトを保護する積極的なアクションにつながることを期待しています。

ウェブにおける Spectre 対策の導入

投機的実行による脆弱性は本質的に低レベルで発生するため、適切なパッチにはユーザーのデバイスのファームウェアやハードウェアの変更が必要になる場合があり、包括的な修正は難しくなります。オペレーティング システムやウェブブラウザのデベロッパーは、可能な限り重要な組み込みの保護機能を実装しています(Google Chrome の out-of-process iframes(プロセス外 iframe) や Cross-Origin Read Blocking(クロスオリジン読み込みブロック)による Site Isolation(サイト分離)、Firefox の Project Fission など)。しかし、既存の API 設計では、データが意図せずに攻撃者のプロセスに流れ込む可能性が残ります。

ウェブ デベロッパーは、この点を考慮してサイトをさらに確実に分離することを検討する必要があります。そのためには、新しいセキュリティ メカニズムを使い、攻撃者によるクロスオリジン リソースへのアクセスを積極的に防ぎます。このような保護は、Spectre スタイルのハードウェア攻撃や一般的なウェブレベルのクロスサイト漏洩の対策となりますが、デベロッパーはそういった脆弱性によるアプリケーションへの脅威を評価し、その対策のデプロイ方法を理解する必要があります。Chrome のウェブ プラットフォーム セキュリティ チームは、この評価に役立ててもらうため、デベロッパー向けの具体的なアドバイスを含む Spectre 後のウェブ開発サイドチャネル攻撃への対策を公開しました。このガイドに従って以下の保護をすることを強くお勧めします。
  • Cross-Origin Resource Policy(CORP)と Fetch メタデータ リクエスト ヘッダーを使うと、イメージやスクリプトなどのリソースを埋め込むことができるサイトを制御して、攻撃者が制御するブラウザのレンダリング プロセスにデータが渡るのを防げます。詳しくは、resourcepolicy.fyi と web.dev/fetch-metadata をご覧ください。
  • Cross-Origin Opener Policy(COOP)を使うと、アプリケーション ウィンドウで他のウェブサイトからの予期しないインタラクションの受け取りを拒否できます。これにより、ブラウザはプロセス内でウィンドウを分離できるようになります。これは重要なプロセスレベルの保護を追加することになり、完全なサイト分離を有効化できないブラウザで特に重要になります。詳しくは、web.dev/coop-coep をご覧ください。
  • Cross-Origin Embedder Policy(COEP)を使うと、アプリケーションがリクエストした認証済みリソースの読み込みを明示的にオプトインできます。 現在、Chrome や Firefox の機密性が高いアプリケーションでプロセスレベルの分離を保証するには、COEP と COOP の両方を有効化する必要があります。詳しくは、web.dev/coop-coep をご覧ください。
アプリケーションでは、これらの分離メカニズムに加えて、X-Frame-Options ヘッダーや X-Content-Type-Options ヘッダーなどの標準の保護も有効化し、SameSite Cookie を使うようにしてください。多くの Google 製アプリケーションでは、このようなメカニズムをすでに導入しているか、現在導入の過程にあります。このようなメカニズムは、デフォルトのブラウザ保護が十分でない場合に、投機的実行のバグに対する保護となります。

覚えておくべき重要な点は、この記事で説明したすべてのメカニズムは重要で強力なセキュリティ プリミティブですが、Spectre に対する完全な保護を保証するものではないことです。また、アプリケーションに固有の動作を考慮したデプロイ方法の検討も必要です。セキュリティ関連のエンジニアや研究者の皆さんには、この Spectre の概念実証の利用と貢献をお願いいたします。サイトのセキュリティ状況の確認や改善に役立てていただきたいと考えています。

ヒント : ウェブサイトを Spectre から守るために役立てていただけるよう、Google セキュリティ チームは Spectroscope を作成しました。これは Chrome 拡張機能のプロトタイプで、アプリケーションをスキャンして、さらなる防御が必要になる可能性があるリソースを見つけます。ウェブ分離機能の導入と合わせてご検討ください。

Reviewed by Eiji Kitamura - Developer Relations Team

ウェブ プラットフォームは、セキュリティの土台となる境界線としてオリジンに依存しています。また、ブラウザは、あるオリジンから別のオリジンへの明示的なデータの漏洩をうまく防いでいます。しかし、Spectre のような攻撃から、明示的でないデータ漏洩への対策が必要になることがわかります。このような攻撃では、サイドチャネルが悪用され、攻撃者のコードを実行するプロセスに入ったあらゆるデータが攻撃者に読み取られることが実証されています。現在、こういった攻撃の実現性はかなり高く、ユーザーにとってのリスクは現実のものとなっています。

機密データが意図せずに攻撃者のプロセスに入り込まないようにしなくてはなりません。ブラウザは、この責任の大部分を背負っています。Chromium の Site Isolation(サイト分離)は、アクセスしたサイトを OS レベルで専用のプロセスに隔離します。Cross-Origin Read Blocking = CORB(クロスオリジン読み込みブロック)は、そのままでは保護されないクロスオリジンリソースの一部が攻撃者に読み込まれることを防ぎます。攻撃者の帯域幅を大幅に増やす API(SharedArrayBuffer など)は、クロスオリジン分離コンテキストにロックされます。しかし、この最後のメカニズムは、ブラウザが単独では行えない作業を指しています。

ウェブ デベロッパーはアプリケーションを熟知しており、各ページやリソースの漏洩によるリスクを情報に基づいて判断できます。ユーザーのデータが漏洩することを防ぐため、ウェブ デベロッパーはホストしているリソースを評価し、適切にリソースを分離するようブラウザに指示するという対策をとる必要があります。概念レベルでは、この対策は次の要素で構成されます。

  1. 受信したヘッダーを調べ、一方で Origin ヘッダー、もう一方で Sec-Fetch- で始まる各ヘッダーに注目し、リクエストに応答するべきかどうかを判断します。
  2. 攻撃者がリソースをサブリソースとして読み込む機能を制限します。これをするには、Cross-Origin Resource Policy として same-origin を設定します(必要な場合のみ、same-site または cross-origin にします)。
  3. 攻撃者がリソースをドキュメントとしてフレームに含めることができるかを制限します。これをするには、X-Frame-Options: SAMEORIGIN を使ってフレーム化保護にオプトインするか、さらに細かい制御が可能な CSP の frame-ancestors ディレクティブを使います。たとえば、frame-ancestors 'self' https://trusted.embedder とします。
  4. 攻撃者がアプリケーションのウィンドウを参照する機能を制限します。これをするには、Cross-Origin Opener Policy を設定します。制限が強い same-origin 値をデフォルトとし、必要な場合のみ same-origin-allow-popups または unsafe-none にするのが最適です。
  5. MIME-type confusion 攻撃を防ぎ、Cross-Origin Read Blocking(クロスオリジン読み込みブロック)などの消極的防御の確実性を高めます。これをするには、正しい Content-Type ヘッダーを設定し、X-Content-Type-Options: nosniff となっていることをグローバルで確認します。

    以上のさまざまな防御策を合わせれば、サイト分離が利用できるかどうかにかかわらず、すべてのブラウザでユーザーのデータに対してある程度の保護をプロセスレベルで提供できます。

    これらの防御策の適用に関する詳しい情報は、Spectre 後のウェブ開発をご覧ください。以上で説明したセキュリティ プリミティブがどのようにサイト上のリソースに適用されるかについて、詳しく説明する実例も含まれています。

    ここで示したのは、明示的でないデータ漏洩からオリジンを守るために、すぐにでも実施できる有用な手順です。今後は、ウェブの各種デフォルトを安全なものに移行し、デベロッパーが何もしなくてもこういった攻撃からユーザーを守れるようにしたいと考えています。
    Reviewed by
    Eiji Kitamura - Developer Relations Team

    ウェブ プラットフォームは、セキュリティの土台となる境界線としてオリジンに依存しています。また、ブラウザは、あるオリジンから別のオリジンへの明示的なデータの漏洩をうまく防いでいます。しかし、Spectre のような攻撃から、明示的でないデータ漏洩への対策が必要になることがわかります。このような攻撃では、サイドチャネルが悪用され、攻撃者のコードを実行するプロセスに入ったあらゆるデータが攻撃者に読み取られることが実証されています。現在、こういった攻撃の実現性はかなり高く、ユーザーにとってのリスクは現実のものとなっています。

    機密データが意図せずに攻撃者のプロセスに入り込まないようにしなくてはなりません。ブラウザは、この責任の大部分を背負っています。Chromium の Site Isolation(サイト分離)は、アクセスしたサイトを OS レベルで専用のプロセスに隔離します。Cross-Origin Read Blocking = CORB(クロスオリジン読み込みブロック)は、そのままでは保護されないクロスオリジンリソースの一部が攻撃者に読み込まれることを防ぎます。攻撃者の帯域幅を大幅に増やす API(SharedArrayBuffer など)は、クロスオリジン分離コンテキストにロックされます。しかし、この最後のメカニズムは、ブラウザが単独では行えない作業を指しています。

    ウェブ デベロッパーはアプリケーションを熟知しており、各ページやリソースの漏洩によるリスクを情報に基づいて判断できます。ユーザーのデータが漏洩することを防ぐため、ウェブ デベロッパーはホストしているリソースを評価し、適切にリソースを分離するようブラウザに指示するという対策をとる必要があります。概念レベルでは、この対策は次の要素で構成されます。

    1. 受信したヘッダーを調べ、一方で Origin ヘッダー、もう一方で Sec-Fetch- で始まる各ヘッダーに注目し、リクエストに応答するべきかどうかを判断します
    2. 攻撃者がリソースをサブリソースとして読み込む機能を制限します。これをするには、Cross-Origin Resource Policy として same-origin を設定します(必要な場合のみ、same-site または cross-origin にします)。
    3. 攻撃者がリソースをドキュメントとしてフレームに含めることができるかを制限します。これをするには、X-Frame-Options: SAMEORIGIN を使ってフレーム化保護にオプトインするか、さらに細かい制御が可能な CSP の frame-ancestors ディレクティブを使います。たとえば、frame-ancestors 'self' https://trusted.embedder とします。
    4. 攻撃者がアプリケーションのウィンドウを参照する機能を制限します。これをするには、Cross-Origin Opener Policy を設定します。制限が強い same-origin 値をデフォルトとし、必要な場合のみ same-origin-allow-popups または unsafe-none にするのが最適です。
    5. MIME-type confusion 攻撃を防ぎCross-Origin Read Blocking(クロスオリジン読み込みブロック)などの消極的防御の確実性を高めます。これをするには、正しい Content-Type ヘッダーを設定し、X-Content-Type-Options: nosniff となっていることをグローバルで確認します。

    以上のさまざまな防御策を合わせれば、サイト分離が利用できるかどうかにかかわらず、すべてのブラウザでユーザーのデータに対してある程度の保護をプロセスレベルで提供できます。

    これらの防御策の適用に関する詳しい情報は、Spectre 後のウェブ開発をご覧ください。以上で説明したセキュリティ プリミティブがどのようにサイト上のリソースに適用されるかについて、詳しく説明する実例も含まれています。

    ここで示したのは、明示的でないデータ漏洩からオリジンを守るために、すぐにでも実施できる有用な手順です。今後は、ウェブの各種デフォルトを安全なものに移行し、デベロッパーが何もしなくてもこういった攻撃からユーザーを守れるようにしたいと考えています。


    Reviewed by Eiji Kitamura - Developer Relations Team