概要
1 月 3 日、Project Zero は、プロセスが(最悪の場合)任意のメモリ(そのプロセスに属していないメモリを含む)を読み取ることができる最新の CPU の脆弱性を公開しました。これらの脆弱性は Spectre と Meltdown と名付けられました。Chrome はウェブの安全性を維持するためにどのような取り組みを行っており、ウェブ デベロッパーは自分のサイトに対してどのような対応をすべきですか?
要約
ウェブを閲覧するユーザーは、オペレーティング システムとブラウザを最新の状態に保つ必要があります。また、Chrome ユーザーは サイト分離を有効にすることを検討できます。
ウェブ デベロッパーの方は、Chrome チームからの推奨事項をご確認ください。
- 可能な場合は、
SameSite
とHTTPOnly
の Cookie 属性を使用して、document.cookie
からの読み取りを回避し、Cookie がレンダラ プロセスのメモリに侵入するのを防ぎます。 - サイト分離を有効にしているユーザーに対して クロスオリジン読み取りブロックを最大限に活用するには、MIME タイプが正しいことを確認し、ユーザー固有または機密性の高いコンテンツを含む URL に
X-Content-Type-Options: nosniff
ヘッダーを指定します。 - サイト分離を有効にして、サイトに問題が発生した場合は Chrome チームに報告してください。
これらの手順が役立つ理由については、以下をご覧ください。
リスク
これらの脆弱性についてはさまざまな説明がされていますので、ここでは説明を省略します。これらの脆弱性がどのように悪用されるかについては、Google Cloud チームの同僚によるブログ投稿をご覧ください。
Meltdown と Spectre の両方で、プロセスが読み取りできないメモリを読み取る可能性があります。異なるサイトの複数のドキュメントが Chrome でプロセスを共有することがあります。これは、window.open
、<a href="..." target="_blank">
、または iframe を使用して一方が他方をオープンした場合に発生する可能性があります。ウェブサイトにユーザー固有のデータが含まれている場合、別のサイトがこれらの新しい脆弱性を利用してそのユーザーデータを読み取る可能性があります。
リスクの軽減
Chrome と V8 のエンジニアリング チームは、この脅威を軽減するために複数の取り組みを行っています。
サイト分離
機密データが攻撃者が制御するコードとプロセスを共有しないようにすることで、Spectre の悪用による影響を大幅に軽減できます。Chrome チームは、この目的を達成するための機能である「サイト分離」の開発に取り組んでいます。
サイト分離は、いくつかの既知の問題があり、Chrome チームが可能な限り多くのフィールドテストを実施したいと考えているため、まだデフォルトで有効になっていません。ウェブ デベロッパーは、サイト分離を有効にして、サイトが引き続き機能するかどうかを確認する必要があります。今すぐオプトインする場合は、chrome://flags#enable-site-per-process
を有効にします。動作しないサイトを見つけた場合は、バグを報告して、サイト分離が有効になっていることをお知らせください。
クロスサイト ドキュメントのブロック
すべてのクロスサイト ページが個別のプロセスに配置されている場合でも、ページは画像や JavaScript などのクロスサイト サブリソースを正当にリクエストできます。機密情報が漏洩しないように、サイト分離には、レンダラ プロセスに配信されるネットワーク レスポンスを制限する「クロスサイト ドキュメントのブロック」機能が含まれています。
ウェブサイトは、サーバーから「ドキュメント」と「リソース」の 2 種類のデータをリクエストできます。ここで、ドキュメントは HTML、XML、JSON、テキスト ファイルです。ウェブサイトは、独自のドメインまたは許可付き CORS ヘッダーを持つ他のドメインからドキュメントを受信できます。リソースには、画像、JavaScript、CSS、フォントなどがあります。リソースは任意のサイトから含めることができます。
クロスサイト ドキュメントのブロック ポリシーは、次の場合に、プロセスが他のオリジンから「ドキュメント」を受信しないようにします。
- MIME タイプが HTML、XML、JSON、text/plain のいずれかである。
X-Content-Type-Options: nosniff
HTTP レスポンス ヘッダーが含まれているか、簡単なコンテンツ分析(「スニッフィング」)でタイプが正しいことが確認されている- CORS でドキュメントへのアクセスが明示的に許可されていない
このポリシーによってブロックされたドキュメントは、空としてプロセスに提示されますが、リクエストはバックグラウンドで引き続き行われます。
たとえば、攻撃者が <img src="https://yourbank.com/balance.json">
などの機密データを含む JSON ファイルを含む <img>
タグを作成したとします。サイト分離がないと、JSON ファイルの内容がレンダラ プロセスのメモリに保存されます。この時点で、レンダラは有効な画像形式ではないことを認識し、画像をレンダリングしません。しかし、Spectre により、そのメモリのチャンクを読み取る方法が見つかりました。クロスサイト ドキュメント ブロッキングでは MIME タイプがブロックされるため、このファイルの内容がレンダラが実行されているプロセスのメモリに格納されることは決してありません。
ユーザー指標によると、text/html
または text/plain
MIME タイプで配信される JavaScript ファイルと CSS ファイルが多数あります。誤ってドキュメントとしてマークされたリソースをブロックしないように、Chrome はレスポンスのスニッフィングを試みて、MIME タイプが正しいことを確認します。このスニッフィングは不完全であるため、ウェブサイトで正しい Content-Type
ヘッダーが設定されていることを確認している場合は、すべてのレスポンスに X-Content-Type-Options: nosniff
ヘッダーを追加することをおすすめします。
クロスサイト ドキュメント ブロッキングを試す場合は、上記の方法でサイト分離を有効にします。
Cookie の数: SameSite
上記の例 <img
src="https://yourbank.com/balance.json">
に戻りましょう。これは、yourbank.com にユーザーを自動的にログインさせる Cookie が保存されている場合にのみ機能します。通常、Cookie は、Cookie を設定するウェブサイトへのすべてのリクエストで送信されます。リクエストが <img>
タグを使用してサードパーティによって行われた場合でも同様です。SameSite Cookie は、Cookie を同じサイトから発信されたリクエストにのみ添付することを指定する新しい属性です。残念ながら、本ドキュメントの執筆時点で、この属性をサポートしているのは Chrome と Firefox 58 以降のみです。
HTTPOnly
、document.cookie
サイトの Cookie がクライアント JavaScript ではなくサーバーサイドでのみ使用されている場合は、Cookie のデータがレンダラ プロセスに送信されないようにする方法があります。HTTPOnly
クッキー属性を設定すると、Chrome などのサポートされているブラウザでクライアントサイド スクリプトからクッキーにアクセスできないように明示的にできます。HTTPOnly
を設定できない場合は、絶対に必要な場合を除き document.cookie
を読み取らないことで、レンダリング プロセスへの読み込み Cookie データの公開を制限できます。
rel="noopener"
を使用して外部リンクを開く
target="_blank"
を使用して別のページにリンクすると、開いたページは window
オブジェクトにアクセスし、ページを別の URL に移動できます。サイト分離がない場合、そのページは現在のページと同じプロセスになります。ページの保護を強化するため、新しいウィンドウで開く外部ページへのリンクには常に rel="noopener"
を指定する必要があります。
高解像度タイマー
Meltdown または Spectre を悪用するには、攻撃者はメモリから特定の値を読み取るのにかかる時間を測定する必要があります。そのためには、信頼性が高く正確なタイマーが必要です。
ウェブ プラットフォームが提供する API の 1 つが performance.now()
で、精度は 5 マイクロ秒です。緩和策として、すべての主要ブラウザで performance.now()
の解像度を下げて、攻撃を難しくしています。
高解像度タイマーを取得するもう 1 つの方法は、SharedArrayBuffer を使用することです。このバッファは、専用のワーカーがカウンタをインクリメントするために使用します。メインスレッドは、このカウンタを読み取り、タイマーとして使用します。当面の間、ブラウザは他の緩和策が講じられるまで SharedArrayBuffer を無効にすることにしました。
V8
Spectre を悪用するには、特別に作成された CPU 命令のシーケンスが必要です。V8 チームは既知の攻撃の概念実証に対する緩和策を実装しており、これらの攻撃がトリガーされた場合でも生成されたコードを安全にするための、最適化コンパイラである TurboFan の変更に取り組んでいます。ただし、これらのコード生成の変更によりパフォーマンスが低下する可能性があります。
ウェブの安全性を確保する
Spectre と Meltdown の検出とその影響については、多くの不確実性がありました。この記事が、ウェブ プラットフォームの安全を守るために Chrome チームと V8 チームが行っている取り組みと、ウェブ デベロッパーが既存のセキュリティ機能を活用して貢献できる方法について、理解を深める一助となれば幸いです。ご不明な点がございましたら、Twitter でお問い合わせください。