コンテンツにスキップ

セキュリティモデル

この記事では、Cloudflareのセキュリティアーキテクチャの概要を説明し、次にV8のバグとSpectreに関する2つのよくある質問について取り上げます。

Workersプロジェクトの開始以来、セキュリティは高い優先事項でした。共有インフラストラクチャ上で多数のテナントをホスティングする際に、さまざまな種類のサイドチャネルが脅威となる可能性があるという懸念がありました。Cloudflare Workersランタイムは、サイドチャネル攻撃に対抗するよう慎重に設計されています。

この目的のために、Workersはコードがローカルで自分自身の実行時間を測定することを不可能にするように設計されています。たとえば、Date.now()によって返される値は、コードが実行されている間は固定されています。他のタイマーは提供されていません。さらに、Cloudflareは同時実行性(たとえば、マルチスレッド)へのアクセスを提供していません。これは、攻撃者がアドホックタイマーを構築することを可能にする可能性があるためです。これらの設計選択は、既存のアプリケーションが依存しているAPIを削除するため、他のプラットフォーム(たとえば、ウェブブラウザ)に遡及的に導入することはできません。これらは、最初からのランタイム設計の選択によってWorkersでのみ可能でした。

これらの初期の設計決定は効果的であることが証明されていますが、Cloudflareは引き続き防御の深さを追加しており、疑わしいWorkersと高価値のWorkersの間に追加の隔離層を作成するためにWorkersを再スケジュールする技術を含んでいます。

Workersのアプローチは、業界のほとんどが取っているアプローチとは非常に異なります。これは、Spectreスタイルの攻撃の全範囲に対して抵抗力があり、各攻撃に特別な注意を払う必要がなく、一般的に推測をブロックする必要もありません。しかし、Workersのアプローチが異なるため、慎重な研究が必要です。Cloudflareは現在、グラーツ工科大学(TU Graz)の研究者と協力して、これまでに行われたことを研究しています。これらの研究者には、Spectreを最初に発見した人々の一部が含まれています。Cloudflareは、この研究の結果を入手可能になり次第公開します。

詳細については、Cloudflare WorkersのアーキテクトであるKenton Vardaによるこの講演を参照してください。Spectreについては、講演の終わり近くで取り上げられています。

アーキテクチャの概要

Workersランタイムアーキテクチャの簡単な概要から始めます:

Scheduling and routing
Scheduling and routing
HTTP client
HTTP client
HTTP server
HTTP server
Inbound
HTTP proxy
[Not supported by viewer]
Outbound
HTTP proxy
[Not supported by viewer]
Supervisor
[Not supported by viewer]
Main Runtime Process
Main Runtime Process
Outer Sandbox
Outer Sandbox
Disk
Disk
Control plane
[Not supported by viewer]
HTTP
[Not supported by viewer]
Cap'n Proto RPC
[Not supported by viewer]
In-process calls
[Not supported by viewer]
Other
[Not supported by viewer]
V8 Isolate
[Not supported by viewer]
V8 Isolate
[Not supported by viewer]
V8 Isolate
[Not supported by viewer]
V8 Isolate
[Not supported by viewer]
Process
Sandbox
[Not supported by viewer]
V8 Isolate
[Not supported by viewer]
Scheduling and routing
Scheduling and routing
Process
Sandbox
[Not supported by viewer]
V8 Isolate
[Not supported by viewer]
Scheduling and routing
Scheduling and routing

コードサンドボックスを設計する際の2つの基本的な部分は、セキュアな隔離とAPI設計です。

隔離

まず、コードがアクセスしてはいけないものにアクセスできないセキュアな実行環境を作成する必要がありました。

これには、GoogleがChromeで使用するために開発したJavaScriptエンジンであるV8が主なツールです。V8は、コードをアイソレート内で実行し、そのコードがアイソレートの外部のメモリにアクセスするのを防ぎます — 同じプロセス内であっても重要です。これは、Cloudflareが単一のプロセス内で多くのアイソレートを実行できることを意味します。これは、Cloudflareが各マシン上で数千のゲストアプリケーションをホストし、最小限のオーバーヘッドでこれらのゲスト間を毎秒数千回迅速に切り替える必要があるエッジコンピュートプラットフォームにとって不可欠です。Cloudflareが各ゲストのために別々のプロセスを実行しなければならなかった場合、Cloudflareがサポートできるテナントの数は大幅に減少し、Cloudflareはエッジコンピュートを少数の大規模なエンタープライズ顧客に制限しなければならなくなります。アイソレート技術を使用することで、Cloudflareはエッジコンピュートをすべての人に提供できます。

ただし、Cloudflareは時々、Workerを独自のプライベートプロセスでスケジュールすることを決定します。Cloudflareは、Workerが追加の隔離層を必要とする特定の機能を使用している場合にこれを行います。たとえば、開発者がdevtoolsデバッガーを使用してWorkerを検査する場合、CloudflareはそのWorkerを別のプロセスで実行します。これは、歴史的にブラウザでは、インスペクタープロトコルはブラウザの信頼されたオペレーターによってのみ使用可能であり、そのためV8の他の部分と同じくらいのセキュリティの精査を受けていないからです。インスペクタープロトコルのバグのリスクが高まるのを防ぐために、Cloudflareは検査されたWorkersをプロセスレベルのサンドボックスを持つ別のプロセスに移動します。Cloudflareはまた、Spectreに対する追加の防御としてプロセス隔離を使用します。

さらに、他のアイソレートと共有プロセスで実行されるアイソレートに対しても、Cloudflareは各マシン上で全体のランタイムの複数のインスタンスを実行します。これをコルドンと呼びます。Workersは、各Workerに信頼レベルを割り当て、低信頼のWorkersをより高く信頼されているWorkersから分離することによってコルドン間で分配されます。この運用の一例として、無料プランにサインアップした顧客は、エンタープライズ顧客と同じプロセスでスケジュールされることはありません。これは、V8にゼロデイのセキュリティ脆弱性が見つかった場合の防御の深さを提供します。

全プロセスレベルでは、Cloudflareは防御の深さのために別のサンドボックス層を適用します。レイヤー2のサンドボックスは、Linuxの名前空間とseccompを使用して、ファイルシステムとネットワークへのすべてのアクセスを禁止します。名前空間とseccompは、コンテナを実装するために一般的に使用されます。しかし、Cloudflareのこれらの技術の使用は、通常のコンテナエンジンで可能なものよりもはるかに厳格です。なぜなら、Cloudflareはプロセスが開始された後に名前空間とseccompを構成しますが、アイソレートが読み込まれる前に行うからです。たとえば、Cloudflareは(そして実際に使用します)完全に空のファイルシステム(マウント名前空間)を使用し、seccompを使用してファイルシステム関連のシステムコールをすべてブロックします。コンテナエンジンは通常、すべてのファイルシステムアクセスを禁止することはできません。なぜなら、そうすることでディスクからゲストプログラムを開始するためにexec()を使用することが不可能になるからです。Workersの場合、Cloudflareのゲストプログラムはネイティブバイナリではなく、Cloudflareがファイルシステムアクセスをブロックする前にWorkersランタイム自体がすでに読み込みを完了しています。

レイヤー2のサンドボックスは、ネットワークアクセスも完全に禁止します。代わりに、プロセスは同じシステム上の他のプロセスと通信するためにローカルUNIXドメインソケットを介してのみ制限されます。外部世界への通信は、サンドボックスの外にある他のローカルプロセスによって仲介されなければなりません。

特に、スーパーバイザーと呼ばれるプロセスは、ディスクまたは他の内部サービスからWorkerコードと構成を取得する責任があります。スーパーバイザーは、サンドボックスプロセスが実行すべきWorkersに関連する構成以外は読み取れないことを保証します。

たとえば、サンドボックスプロセスが以前に見たことのないWorkerのリクエストを受け取ると、そのリクエストにはそのWorkerのコードの暗号化キーが含まれています。サンドボックスは、そのキーをスーパーバイザーに渡してコードをリクエストできます。サンドボックスは、適切なキーを受け取っていないWorkerをリクエストすることはできません。既知のWorkersを列挙することもできません。また、必要のない構成をリクエストすることもできません。たとえば、WorkerへのHTTPSトラフィックに使用されるTLSキーをリクエストすることはできません。

構成を読み取ること以外に、サンドボックスがシステム上の他のプロセスと通信する理由は、Workersに公開されるAPIを実装するためです。

API設計

「木が森で倒れたとき、誰もそれを聞いていなければ音がするのか?」という言葉があります。Cloudflareの言葉では、「Workerが外部世界との通信を完全に防がれた完全に隔離された環境で実行される場合、それは実際に実行されるのか?」ということです。

完全なコードの隔離は、実際には無意味です。Workersが何か有用なことをするためには、ユーザーと通信できる必要があります。少なくとも、Workerはリクエストを受け取り、それに応答できる必要があります。Workersが世界にリクエストを安全に送信するためには、APIが必要です。

サンドボックス化の文脈において、API設計は新たな責任のレベルを持ちます。CloudflareのAPIは、Workerが何をできるか、何をできないかを正確に定義します。Cloudflareは、各APIを設計する際に、許可された操作のみを表現できるように非常に注意を払わなければなりません。たとえば、CloudflareはWorkersがHTTPリクエストを作成し、受信できるようにしたいと考えていますが、ローカルファイルシステムや内部ネットワークサービスにアクセスできるようにはしたくありません。

現在、Workersはローカルファイルシステムへのアクセスを一切許可していません。したがって、CloudflareはファイルシステムAPIをまったく公開していません。APIがないということは、アクセスがないということです。

しかし、将来的にWorkersがローカルファイルシステムアクセスをサポートしたいと考えた場合、それはどのように行われるのでしょうか?Workersはファイルシステム全体を見るべきではありません。ただし、各Workerがファイルシステム上に自分のプライベートディレクトリを持ち、好きなものを保存できると想像してみてください。

これを実現するために、Workersは能力ベースのセキュリティに基づく設計を使用します。能力は大きなトピックですが、この場合、CloudflareはWorkerにファイルシステム上のディレクトリを表すDirectory型のオブジェクトを与えることを意味します。このオブジェクトには、ファイルやサブディレクトリを作成および開くためのAPIがあり、親ディレクトリを上に移動することは許可されていません。実質的に、各Workerは自分のプライベートDirectoryを自分のファイルシステムのルートのように見ることができます。

そのようなAPIはどのように実装されるのでしょうか?上記のように、サンドボックスプロセスは実際のファイルシステムにアクセスできません。代わりに、ファイルアクセスはスーパーバイザープロセスによって仲介されます。サンドボックスは、Cap’n Proto RPCを使用してスーパーバイザーと通信します。これは、能力ベースのRPCプロトコルです。(Cap’n Protoは、現在Cloudflare Workersチームによって維持されているオープンソースプロジェクトです。)このプロトコルは、能力ベースのAPIを実装するのを非常に簡単にするため、Cloudflareはサンドボックスが実行しているWorkersに属するファイルにのみアクセスするように厳密に制限できます。

では、ネットワークアクセスについてはどうでしょうか?現在、WorkersはHTTPを介してのみ外部世界と通信することが許可されています — 受信および送信の両方です。他の形式のネットワークアクセスのためのAPIは存在しないため、それは禁止されています。ただし、Cloudflareは将来的に他のプロトコルをサポートする計画です。

前述のように、サンドボックスプロセスはネットワークに直接接続することはできません。代わりに、すべてのアウトバウンドHTTPリクエストは、ローカルプロキシサービスにUNIXドメインソケットを介して送信されます。そのサービスはリクエストに制限を実装します。たとえば、そのリクエストがパブリックインターネットサービスまたはWorkerのゾーンのオリジンサーバーに宛てられていることを確認し、ローカルマシンやネットワーク上で可視化される可能性のある内部サービスには宛てられないようにします。また、すべてのリクエストに、どのWorkerから発信されたかを識別するヘッダーが追加されるため、悪用されたリクエストを追跡してブロックできます。すべてが整ったら、リクエストはCloudflareネットワークのHTTPキャッシングレイヤーに送信され、インターネットに出て行きます。

同様に、インバウンドHTTPリクエストはWorkersランタイムに直接到達しません。最初にインバウンドプロキシサービスによって受信されます。そのサービスはTLS終端(WorkersランタイムはTLSキーを決して見ません)を担当し、特定のリクエストURLに対して実行する正しいWorkerスクリプトを特定します。すべてが整ったら、リクエストはUNIXドメインソケットを介してサンドボックスプロセスに渡されます。

V8のバグとパッチギャップ

すべての非自明なソフトウェアにはバグがあり、サンドボックス技術も例外ではありません。仮想マシン、コンテナ、アイソレート — Workersが使用するもの — もバグを持っています。

Workersは、GoogleがChromeで使用するために構築したJavaScriptエンジンであるV8によって提供される隔離に大きく依存しています。これには利点と欠点があります。一方では、V8は非常に複雑な技術であり、仮想マシンよりも広い攻撃面を作成します。より多くの複雑さは、何かが間違う機会を増やします。しかし、V8のバグを見つけて修正するために膨大な努力が注がれています。これは、世界で最も人気のあるサンドボックス技術の1つであるためです。Googleは、V8のサンドボックスエスケープを見つけた人に対して5桁の報奨金を定期的に支払っています。Googleはまた、ほとんどの人間よりも早くバグを自動的に見つけるファジングインフラを運営しています。Googleの投資は、V8のゼロデイの危険を最小限に抑えるのに大いに役立っています — 悪意のある行為者によって見つけられ、Googleには知られていないバグです。

しかし、バグが見つかり報告された後はどうなるのでしょうか?V8はオープンソースであるため、セキュリティバグの修正はオープンに開発され、同時にすべての人にリリースされます。悪意のある行為者がエクスプロイトを開発する前に、パッチができるだけ早く本番環境に展開されることが重要です。

修正を公開してから展開するまでの時間は、パッチギャップとして知られています。Googleは以前、Chromeのパッチギャップが33日から15日に短縮されたと発表しました。

幸いなことに、CloudflareはWorkersランタイムが動作するマシンを直接制御しています。ビルドとリリースプロセスのほぼすべてが自動化されているため、V8のパッチが公開されると、Cloudflareのシステムは自動的に新しいWorkersランタイムのリリースをビルドし、必要な(人間の)レビュアーからのワンクリックの承認の後、自動的にそのリリースを本番環境にプッシュします。

その結果、Workersのパッチギャップは現在24時間未満です。ミュンヘンのV8チームによって公開されたパッチは、通常、米国の労働時間の終わりまでに本番環境に展開されます。

Spectre: はじめに

GoogleのV8チームは、V8自体がSpectreに対抗できないと述べています。Workersはこれに依存する必要はありません。Workers環境は、Spectreを軽減するための多くの代替アプローチを提供します。

それは何ですか?

Spectreは、悪意のあるプログラムがCPUを騙して、プログラムがアクセスすることを許可されていないデータを使用して推測的に計算を行わせる攻撃のクラスです。最終的にCPUは問題に気付き、プログラムが推測的計算の結果を見ることを許可しません。しかし、プログラムはキャッシュへの影響など、計算の微妙な副作用を観察することで秘密データのビットを導き出すことができるかもしれません。

Spectreに関する詳細情報は、このトピックに関するLearning Centerのページを参照してください。

なぜWorkersにとって重要なのか?

Spectreは、現代のCPUに存在するさまざまな脆弱性を包含しています。特定の脆弱性はアーキテクチャやモデルによって異なり、まだ発見されていない多くの脆弱性が存在する可能性があります。

これらの脆弱性は、すべてのクラウドコンピューティングプラットフォームにとって問題です。同じマシン上で複数のテナントがコードを実行している場合、Spectre攻撃が可能です。しかし、テナントが近接しているほど、特定の脆弱性を軽減することが難しくなります。既知の多くの問題は、カーネルレベル(プロセス間の保護)やハイパーバイザーレベル(VMの保護)で軽減でき、しばしばCPUマイクロコードの更新やさまざまな防御策の助けを借りて行われます(これらの多くは深刻なパフォーマンスへの影響を伴うことがあります)。

Cloudflare Workersでは、テナントはV8アイソレートを使用して互いに隔離されています — プロセスやVMではありません。これは、WorkersがSpectreを防ぐためにOSやハイパーバイザーのパッチに必ずしも依存できないことを意味します。Workersは独自の戦略が必要です。

なぜプロセス隔離を使用しないのか?

Cloudflare Workersは、すべてのCloudflareロケーションでコードを実行するように設計されています。

Workersは、すべての人がアクセスできるプラットフォームとして設計されています。多くのテナントが非常に少ないトラフィックを受けるため、膨大な数のテナントを処理する必要があります。

これら2つのポイントを組み合わせると、計画が難しくなります。

典型的な非エッジサーバーレスプロバイダーは、低トラフィックのテナントを処理するために、そのテナントのすべてのトラフィックを単一のマシンに送信し、アプリケーションのコピーを1つだけロードすることができます。もしそのマシンが、たとえば、十数のテナントを処理できるのであれば、それで十分です。そのマシンは、数百万台のマシンを持つ巨大なデータセンターにホストされ、規模の経済を達成します。しかし、この集中化は、ユーザーが近くにいない場合、レイテンシや世界的な帯域幅コストを引き起こします。

一方、Workersでは、トラフィックレベルに関係なく、すべてのテナントが現在すべてのCloudflareロケーションで実行されています。そして、エンドユーザーにできるだけ近づくことを目指す中で、Cloudflareは時々、限られた数のマシンしか収容できないロケーションを選択します。その結果、Cloudflareは、マシンごとに数千のアクティブなテナントをホストできる必要があり、非アクティブなテナントをオンデマンドで迅速に立ち上げる能力が求められます。つまり、各ゲストは数メガバイトのメモリを超えることができず、コールスタックやプロセスが必要とするすべてのものを収容するにはほとんど不十分です。

さらに、Cloudflareはコンテキストスイッチングを計算効率的に行う必要があります。メモリに常駐する多くのWorkersは、時折しかイベントを処理せず、多くのWorkersは特定のイベントに対してミリ秒の一部未満の時間を費やします。この環境では、単一のコアが毎秒数千の異なるテナント間でスイッチングすることが容易にあります。1つのイベントを処理するためには、ゲストアプリケーションとそのホスト間でかなりの量の通信が必要であり、さらにスイッチングと通信のオーバーヘッドが発生します。各テナントが独自のプロセスに存在する場合、すべてのオーバーヘッドは、多くのテナントが単一のプロセスに存在する場合よりも桁違いに大きくなります。Workersで厳密なプロセス隔離を使用すると、CPUコストは共有プロセスの10倍になることがあります。

Workersを安価で迅速、かつすべての人にアクセス可能に保つために、Cloudflareは単一のプロセスで複数のテナントをホストする方法を見つける必要がありました。

Spectreの修正はない

Spectreには公式な解決策はありません。重い仮想マシンを使用しても同様です。誰もが依然として脆弱です。

業界は新しいSpectre攻撃に直面しています。数ヶ月ごとに、研究者は新しいSpectre脆弱性を発見し、CPUベンダーは新しいマイクロコードをリリースし、OSベンダーはカーネルパッチをリリースします。誰もが引き続き更新を行わなければなりません。

しかし、最新のパッチを展開するだけで十分なのでしょうか?

まだ公表されていない脆弱性が存在します。Spectreに対抗するために、Cloudflareは異なるアプローチを取る必要がありました。個々の既知の脆弱性をブロックするだけでは不十分です。代わりに、脆弱性の全クラスに一度に対処する必要があります。

防御の構築

Spectreに対する包括的な修正が見つかる可能性は低いですが、以下の思考実験は考慮すべきポイントを提起します。

根本的に、すべてのSpectre脆弱性は、隠れたプロセッサの状態を検出するためにサイドチャネルを使用します。サイドチャネルは、定義上、システムの非決定的な動作を観察することを含みます。便利なことに、ほとんどのソフトウェア実行環境は、非決定性を排除するために努力しています。なぜなら、非決定的な実行はアプリケーションを信頼性のないものにするからです。

しかし、依然として一般的な非決定性のいくつかの種類があります。その中で最も明白なのはタイミングです。業界は、プログラムが実行されるたびに同じ時間を要するという考えを長い間放棄しました。なぜなら、決定論的なタイミングは、ヒューリスティックなパフォーマンス最適化と根本的に矛盾するからです。ほとんどのSpectre攻撃は、CPUの隠れたマイクロアーキテクチャ状態を検出する手段としてタイミングに焦点を当てています。

一部の人々は、これを解決するためにタイマーを不正確にしたり、ランダムノイズを追加したりすることを提案しています。しかし、実際には、これでは攻撃を止めることはできず、攻撃を遅くするだけです。タイマーが実際の時間を追跡している場合、タイマーを不正確にするために行うことは、攻撃を何度も実行し、統計を使用して不整合をフィルタリングすることで克服できます。

多くのセキュリティ研究者は、これを物語の終わりと見なしています。攻撃を遅くすることに何の意味があるのでしょうか?攻撃が依然として可能であれば。

カスケード遅延

しかし、攻撃を遅くする手段は強力です。

重要な洞察は次のとおりです:攻撃が遅くなるにつれて、新しい技術が実用的になり、さらに遅くすることができます。目標は、攻撃が非常に遅くなり、興味を失わせるほどの技術を連鎖させることです。

結局のところ、暗号学の多くは、技術的にはブルートフォース攻撃に対して脆弱です — 技術的には、十分な時間があれば破ることができます。しかし、必要な時間が数千年(あるいは数十億年)であれば、これは十分な防御です。

Spectre攻撃を無意味なほど遅くするために何ができるでしょうか?

Spectre攻撃の凍結

ステップ0: ネイティブコードを許可しない

Workersは、顧客がCloudflareネットワーク上で実行するためにネイティブコードのバイナリをアップロードすることを許可していません — JavaScriptとWebAssemblyのみです。Python、Rust、あるいはCobolなどの多くの他の言語は、これらの2つの形式のいずれかにコンパイルまたはトランスパイルできます。どちらもV8を通過して、これらの形式を真のネイティブコードに変換します。

これ自体は、Spectre攻撃を難しくするわけではありません。しかし、これは次のステップを有効にするための基本的なステップ0として提示されています。

ネイティブコードプログラムを受け入れることは、既存のCPUアーキテクチャ(通常はx86)に依存することを意味します。合理的なパフォーマンスでコードを実行するためには、通常、実際のハードウェア上で直接コードを実行する必要があり、その実行がどのように進行するかに対するホストの制御が大幅に制限されます。たとえば、カーネルやハイパーバイザーは、サイドチャネル攻撃に役立つCLFLUSH命令をアプリケーションが呼び出すことを禁止する能力を持っていません。

さらに、ネイティブコードをサポートすることは、既存のオペレーティングシステムやソフトウェアスタック全体をサポートすることを意味し、それに伴い、アーキテクチャがどのように機能するかに関する数十年の期待がもたらされます。たとえば、x86 CPUは、精密なタイマーを読み取るRDTSC命令をカーネルやハイパーバイザーが無効にすることを許可します。しかし、現実的には、これを無効にすると、多くのプログラムがRDTSCを使用して現在の時間を知りたいときに実装されているため、壊れてしまいます。

ネイティブコードをサポートすることは、将来の軽減技術における選択肢を制限します。抽象的な中間形式を使用することで、より大きな自由があります。

ステップ1: タイマーとマルチスレッドを禁止する

Workersでは、JavaScript Date APIを使用して現在の時間を取得することができますが、Date.now()を呼び出すことで得られる時間値は現在の時間ではありません。Date.now()は、最後のI/Oの時間を返します。コード実行中は進行しません。たとえば、攻撃者が次のように書いた場合:

let start = Date.now();
for (let i = 0; i < 1e6; i++) {
doSpectreAttack();
}
let end = Date.now();

startendの値は常に正確に同じになります。攻撃者は、攻撃を実行するために必要なコードの実行時間を測定するためにDateを使用できません。

同様に、Workersではマルチスレッドと共有メモリは許可されていません。1つのイベントの処理に関連するすべてのことは、同じスレッドで行われます。そうでなければ、スレッドを競わせて基礎となるタイマーを推測して確認することができてしまいます。複数のWorkersが同じリクエストを同時に処理することは許可されていません。たとえば、あなたのゾーンにWorkersを使用して実装されたCloudflareアプリがインストールされていて、あなたのゾーン自体もWorkersを使用している場合、あなたのゾーンへのリクエストは実際には2つのWorkersによって順番に処理されることがあります。これらは同じスレッドで実行されます。

この時点で、ローカルでのコード実行時間の測定は防止されています。しかし、リモートで測定することはまだ可能です。たとえば、Workerの実行をトリガーするリクエストを送信しているHTTPクライアントは、Workerが応答するまでの時間を測定できます。このような測定は、インターネットを通過し、一般的なネットワーキングコストを負担するため、非常にノイジーである可能性が高いです。このようなノイズは、理論的には、攻撃を何度も実行し、平均を取ることで克服できます。

敵対的なテストとSpectreの専門家の助けを借りて、Cloudflareは本番環境で機能するリモートタイミング攻撃を開発できませんでした。しかし、機能する攻撃がないからといって、Workersが防御を構築するのをやめるべきではありません。むしろ、Workersチームは現在、いくつかのより高度な対策をテストしています。

ステップ2: 動的プロセス隔離

攻撃が可能であれば、それを実行するのに長い時間がかかるでしょう — 少なくとも数時間、場合によっては数週間かかるかもしれません。しかし、攻撃が1秒でも実行されると、新たなデータが大量に生成され、さらなる対策を引き起こすことができます。

Spectre攻撃は、通常のプログラムでは見られない異常な動作を示します。これらの攻撃は、マイクロアーキテクチャの効果を増幅するために病的なパフォーマンスシナリオを作り出そうと意図的に試みます。これは、攻撃が他の軽減策を克服するためにループ内で数十億回実行されることを強いられた場合に特に当てはまります。これは、CPUパフォーマンスカウンターのようなメトリクスに現れる傾向があります。

さて、Spectre攻撃を検出するためにパフォーマンスメトリクスを使用する際の通常の問題は、時折偽陽性が発生することです。時には、正当なプログラムがパフォーマンスが悪いことがあります。ランタイムは、パフォーマンスが悪いすべてのアプリケーションをシャットダウンすることはできません。

代わりに、ランタイムは、疑わしいパフォーマンスメトリクスを持つWorkersを自分のプロセスに再スケジュールすることを選択します。上記のように、ランタイムはすべてのWorkerに対してこれを行うことはできません。なぜなら、オーバーヘッドが高すぎるからです。しかし、防御メカニズムとしていくつかのWorkerプロセスを隔離することは許容されます。Workerが正当であれば、少しのオーバーヘッドで動作し続けます。幸いなことに、CloudflareはほぼいつでもWorkerを独自のプロセスに移動させることができます。

実際、詳細なパフォーマンスカウンターに基づくトリガーは、ここでは必要ないかもしれません。Workerがイベントごとに大量のCPU時間を使用する場合、そのプロセスに隔離するオーバーヘッドは相対的に少なくなります。したがって、ランタイムはCPUを多く消費するWorkerに対してプロセス隔離を使用することができます。

Workerが隔離されると、CloudflareはほとんどのデスクトップWebブラウザが行っているように、オペレーティングシステムのSpectre防御に依存できます。

Cloudflareは、このアプローチを開発するためにグラーツ工科大学の専門家と協力しています。TU GrazのチームはSpectre自体を共同発見し、それ以来、多くのフォローアップ発見に責任を持っています。Cloudflareは、Workersを動的に隔離する能力を開発し、攻撃を確実に検出するメトリクスを特定しました。

前述のように、プロセス隔離は完全な防御ではありません。時間が経つにつれて、Spectre攻撃は実行にかかる時間が遅くなる傾向があり、Cloudflareは悪意のある行為者を合理的に推測し、特定する能力を持っています。プロセスを隔離することで、潜在的な攻撃がさらに遅くなります。

ステップ3: 定期的な全メモリシャッフル

この時点で、知られているすべての攻撃は防がれています。これにより、Workersは将来の未知の攻撃に対して脆弱になりますが、他のすべてのCPUベースのシステムと同様です。しかし、すべての新しい攻撃は一般的に非常に遅く、数日以上かかるため、Cloudflareには防御の準備をする時間があります。

例えば、毎日Workersランタイム全体を再起動することは合理的です。これにより、メモリ内のすべての位置がリセットされ、攻撃者は秘密の位置を発見するプロセスを再開する必要があります。Cloudflareはまた、物理マシンやコーディン間でWorkersを再スケジュールすることができるため、特定の隣接するシステムへの攻撃のウィンドウが制限されます。

一般的に、Workersは根本的にプリエンプティブであるため(コンテナやVMとは異なり)、Cloudflareは攻撃を挫くための自由度が高いです。

Cloudflareはこれを継続的な投資と見なしており、決して完了するものではありません。