多くのウェブ アプリケーションでは、ユーザー制御のコンテンツを表示する必要があります。これには、ユーザーがアップロードした画像(プロフィール写真など)を提供するような簡単なものから、ユーザーが制御する HTML のレンダリングのような複雑なもの(ウェブ開発チュートリアルなど)があります。これまで、この作業を安全に行うことは困難でした。そこで Google では、ほとんどの種類のウェブ アプリケーションに適用できる簡単で安全なソリューションを見つけるよう取り組んできました。
信頼できないコンテンツを隔離するための従来のソリューション
ユーザーが管理するコンテンツを安全に提供する従来のソリューションは、サンドボックス ドメインと呼ばれるものを使用することです。基本的な考え方は、アプリケーションのメインドメインが example.com
の場合、信頼できないすべてのコンテンツを exampleusercontent.com
で配信するというものです。これら 2 つのドメインはクロスサイトであるため、exampleusercontent.com
上の悪意のあるコンテンツが example.com
に影響することはありません。
この方法により、信頼できないあらゆる種類のコンテンツ(画像、ダウンロード、HTML など)を安全に配信できます。画像やダウンロードにこの拡張機能を使用する必要はないと思われるかもしれませんが、そうすれば、特に従来のブラウザでは、コンテンツ スニッフィングのリスクを回避できます。
サンドボックス ドメインは業界全体で広く使われており、長い間適切に機能してきました。ただし、次の 2 つの大きな欠点があります。
- アプリケーションでは多くの場合、コンテンツ アクセスを 1 人のユーザーに制限する必要があり、認証と認可の実装が必要になります。サンドボックス ドメインは意図的にメインのアプリケーション ドメインと Cookie を共有しないため、安全に共有することは非常に困難です。認証をサポートするには、ケーパビリティ URL を使用するか、サンドボックス ドメイン用に個別の認証 Cookie を設定する必要があります。この 2 つ目の方法は、多くのブラウザがデフォルトでクロスサイト Cookie を制限している最新のウェブでは問題となります。
- ユーザー コンテンツはメインサイトから分離されていますが、他のユーザー コンテンツとは分離されていません。このため、悪意のあるユーザー コンテンツがサンドボックス ドメインの他のデータを攻撃するリスクがあります(同一オリジン データを読み取るなど)。
また、リソースが分離されたドメインに明確にセグメント化されているため、サンドボックス ドメインを使用するとフィッシングのリスクを軽減できます。
ユーザー コンテンツを提供するための最新のソリューション
時とともにウェブが進化し、信頼できないコンテンツをより簡単かつ安全に配信する方法が増えています。ここにはさまざまなアプローチが存在します。ここでは、Google で現在幅広く使用されている 2 つのソリューションについて概説します。
アプローチ 1: 非アクティブなユーザー コンテンツを配信する
サイトで非アクティブなユーザー コンテンツ(画像やダウンロードなど、HTML や JavaScript ではないコンテンツ)のみを配信する場合は、隔離されたサンドボックス ドメインがなくても、この作業を安全に行うことができます。主なステップは次の 2 つです。
Content-Type
ヘッダーには、すべてのブラウザでサポートされる、アクティブなコンテンツが含まれないことが保証された既知の MIME タイプを必ず設定してください(判断に迷う場合は、application/octet-stream
が安全な選択です)。- また、ブラウザがレスポンスを完全に分離できるように、必ず以下のレスポンス ヘッダーを設定してください。
レスポンス ヘッダー | 目的 |
---|---|
X-Content-Type-Options: nosniff |
コンテンツの傍受を防止 |
Content-Disposition: attachment; filename="download" |
レンダリングではなくダウンロードをトリガーする |
Content-Security-Policy: sandbox |
コンテンツが別のドメインに配信されるかのようにサンドボックス化される |
Content-Security-Policy: default-src ‘none' |
JavaScript の実行(およびサブリソースの追加)を無効にします。 |
Cross-Origin-Resource-Policy: same-site |
ページがクロスサイトに含まれることを防ぎます |
これらのヘッダーの組み合わせにより、アプリケーションではレスポンスをサブリソースとして読み込むか、ユーザーがファイルとしてダウンロードするかを選択できます。さらに、このヘッダーは CSP サンドボックス ヘッダーと default-src
制限を通じて、ブラウザのバグに対する複数の保護レイヤを提供します。全体として、上記の設定により、この方法で提供されたレスポンスがインジェクションまたは分離の脆弱性につながることはないという高い確信が得られます。
多層防御
上記の解決策は、一般的に XSS に対して十分な防御となりますが、追加のセキュリティ レイヤを提供するために適用できるその他の強化策がいくつかあります。
- IE11 との互換性を確保するために
X-Content-Security-Policy: sandbox
ヘッダーを設定します。 - エンドポイントの埋め込みをブロックするには、
Content-Security-Policy: frame-ancestors 'none'
ヘッダーを設定します。 - 次の方法で、ユーザー コンテンツを隔離されたサブドメインでサンドボックス化します。
<ph type="x-smartling-placeholder">
- </ph>
- 隔離されたサブドメインでユーザー コンテンツを配信する(例: Google では
product.usercontent.google.com
などのドメインを使用)。 Cross-Origin-Opener-Policy: same-origin
とCross-Origin-Embedder-Policy: require-corp
を設定して、クロスオリジン分離を有効にします。
- 隔離されたサブドメインでユーザー コンテンツを配信する(例: Google では
アプローチ 2: アクティブ ユーザー コンテンツを配信する
また、従来のサンドボックス ドメイン アプローチの弱点に悩まされることなく、アクティブなコンテンツ(HTML や SVG 画像など)を安全に配信することもできます。
最も簡単な方法は、Content-Security-Policy: sandbox
ヘッダーを利用してブラウザにレスポンスを分離するよう指示することです。現在、すべてのウェブブラウザでサンドボックス ドキュメントのプロセス分離が実装されているわけではありませんが、ブラウザのプロセスモデルを継続的に改良することで、サンドボックス化されたコンテンツと埋め込みアプリケーションから分離できる可能性があります。SpectreJS とレンダラの不正使用攻撃が脅威モデルの範囲外である場合は、CSP サンドボックスを使用することが十分な解決策となります。
Google では、サンドボックス ドメインのコンセプトをモダナイズすることで、信頼できないアクティブなコンテンツを完全に分離できるソリューションを開発しました。基本的な考え方は次のとおりです。
- 新しいサンドボックス ドメインを作成して、パブリック サフィックス リストに追加します。たとえば、
exampleusercontent.com
を PSL に追加することで、foo.exampleusercontent.com
とbar.exampleusercontent.com
をクロスサイトで確実に分離できます。 *.exampleusercontent.com/shim
に一致する URL はすべて、静的 shim ファイルにルーティングされます。この shim ファイルには、message
イベント ハンドラをリッスンし、受け取ったコンテンツをレンダリングする短い HTML と JavaScript スニペットが含まれています。- これを使用するために、プロダクトは
$RANDOM_VALUE.exampleusercontent.com/shim
への iframe またはポップアップを作成し、postMessage
を使用して信頼できないコンテンツを shim に送信してレンダリングを行います。 - レンダリングされたコンテンツは Blob に変換され、サンドボックス化された iframe 内にレンダリングされます。
従来のサンドボックス ドメイン アプローチとは異なり、この方法ではすべてのコンテンツを固有のサイトに完全に分離します。また、レンダリングするデータの取得をメイン アプリケーションで処理することで、ケーパビリティ URL を使用する必要がなくなります。
まとめ
これら 2 つのソリューションを組み合わせることで、googleusercontent.com
などの従来のサンドボックス ドメインから、サードパーティ Cookie のブロックに対応した、より安全なソリューションに移行できます。Google では、これらのソリューションを使用するためにすでに多くのプロダクトを移行しており、来年にはさらなる移行を計画しています。