1. 導入
このセクションは規範的ではありません。
ウェブプラットフォームがより有用で強力なアプリケーションを可能にするよう拡張されるにつれて、それらのアプリケーションを可能にする機能が、最低限のセキュリティレベルを満たすコンテキストのみで有効化されることがますます重要になります。TAGによる [SECURING-WEB] の勧告の拡張として、本書ではウェブ上での機能悪用の脅威モデル(§ 4.1 脅威モデル 参照)を説明し、新しい機能を仕様化する文書に組み込むべき規範的な要件の概要を示します(§ 7 実装上の考慮事項 参照)。
ここで議論される最も明白な要件は、機密性や個人データへのアクセス権を持つアプリケーションコードが、データの完全性を保証する認証済みチャネルを通じて機密裏に配信されるべきというものです。コードを安全に配信することは、アプリケーションが常にユーザーのセキュリティやプライバシー要件を満たすことを保証するものではありませんが、必要不可欠な前提条件です。
それほど明白でない点としては、認証済みかつ機密性のあるチャネルを通じて配信されるアプリケーションコードだけでは、非セキュアなコンテキストによる強力な機能の利用を制限するには不十分です。§ 4.2 祖先リスク で説明されているように、協力的なフレームは機能に対する、元々堅固であるはずの制限を回避するために悪用される可能性があります。以下に定義されたアルゴリズムは、これらの回避策が困難かつユーザーに明確に認識されるようにします。
以下の例は、続く規範的な本文の要点をまとめたものです:
1.1. トップレベルドキュメント
http://example.com/
が トップレベル閲覧コンテキスト
で開かれた場合、認証済みかつ暗号化されたチャネルで配信されていないため、セキュアコンテキスト ではありません。
https://example.com/
が トップレベル閲覧コンテキスト
で開かれた場合、認証済みかつ暗号化されたチャネルで配信されているため、セキュアコンテキスト です。
同様に、非セキュアコンテキストが新しいウィンドウで https://example.com/
を開いた場合でも、その新しいウィンドウはセキュアコンテキストとなります(オープナーが非セキュアであっても):
1.2. フレームドドキュメント
フレーム化されたドキュメントは、セキュアコンテキストとなる場合があります。これは、潜在的に信頼できるオリジン から配信され、かつ セキュアコンテキスト内に埋め込まれている場合です。つまり:
https://example.com/
が トップレベル閲覧コンテキスト で開かれ、同じく
https://sub.example.com/
をフレームで開いた場合、両方とも認証済みかつ暗号化されたチャネルで配信されているため、セキュアコンテキスト です。
もし https://example.com/
が何らかの方法で http://non-secure.example.com/
をフレーム化できた場合(例えばユーザーが混在コンテンツのチェックを無効化した場合)、トップレベルのフレームはセキュアのままですが、フレーム内のコンテンツはセキュアコンテキストではありません。
逆に https://example.com/
が http://non-secure.example.com/
内でフレーム化されている場合、これはセキュアコンテキスト ではありません。なぜなら、その祖先が認証済みかつ暗号化されたチャネルで配信されていないためです。
1.3. ウェブワーカー
Dedicated Workerはフレーム化されたドキュメントと類似しています。セキュアコンテキストとなるのは、潜在的に信頼できるオリジンから配信され、かつ所有者がセキュアコンテキストである場合のみです:
https://example.com/
が トップレベル閲覧コンテキスト
で開かれ、https://example.com/worker.js
を実行した場合、ドキュメントもワーカーも セキュアコンテキスト です。
http://non-secure.example.com/
が トップレベル閲覧コンテキスト でフレーム化した
https://example.com/
が https://example.com/worker.js
を実行した場合、フレーム内のドキュメントもワーカーも セキュアコンテキスト ではありません。
1.4. 共有ワーカー
複数のコンテキストが共有ワーカーに接続できます。セキュアコンテキストが共有ワーカーを作成した場合、それは セキュアコンテキストとなり、他の セキュアコンテキスト のみが接続可能です。非セキュアコンテキストが共有ワーカーを作成した場合、それは セキュアコンテキストではありません となり、他の非セキュアコンテキストのみが接続可能です。
https://example.com/
が トップレベル閲覧コンテキスト で
https://example.com/worker.js
を共有ワーカーとして実行した場合、ドキュメントもワーカーもセキュアコンテキストとして扱われます。
別の https://example.com/
(例えば新しいウィンドウ内)が トップレベル閲覧コンテキスト
で開かれた場合もセキュアコンテキストなので、セキュアな共有ワーカーへアクセスできます:
https://example.com/
が http://non-secure.example.com/
内でネストされている場合、セキュアなワーカーには接続できません。なぜならセキュアコンテキストではないからです。
同様に、https://example.com/
が http://non-secure.example.com/
内でネストされている状態で
https://example.com/worker.js
を共有ワーカーとして実行した場合、ドキュメントもワーカーも非セキュアとして扱われます。
1.5. サービスワーカー
サービスワーカーは常に セキュアコンテキスト です。セキュアコンテキスト のみが登録でき、クライアントも セキュアコンテキスト のみとなります。
https://example.com/
が トップレベル閲覧コンテキスト で
https://example.com/service.js
を登録した場合、ドキュメントもサービスワーカーもセキュアコンテキストとして扱われます。
2. フレームワーク
このセクションは規範的ではありません。
2.1. WebIDLとの統合
新しい [SecureContext
]
属性がオペレーターに利用可能となっており、
これにより、それらがセキュアコンテキストのみに
公開されることが保証されます。
以下の例が参考になります:
interface ExampleFeature { // この呼び出しはすべてのコンテキストで成功します。Promise <double >calculateNotSoSecretResult (); // この操作は非セキュアコンテキストでは公開されません。 [SecureContext ]Promise <double >calculateSecretResult (); // ここでも同じです:この操作は非セキュアコンテキストでは公開されません。 [SecureContext ]boolean getSecretBoolean (); }; [SecureContext ]interface SecureFeature { // このインターフェースは非セキュアコンテキストでは公開されません。Promise <any >doAmazingThing (); };
仕様策定者は新しい機能を定義する際にこの属性の利用を推奨します。
2.2. HTMLとの統合
2.2.1. 共有ワーカー
SharedWorker
コンストラクターは、セキュアコンテキストが
セキュアではないワーカーに接続しようとした場合、または
非セキュアコンテキストがセキュアなワーカーに接続しようとした場合、"SecurityError
"
DOMException
例外をスローします。
2.2.2. 機能検出
アプリケーションは、セキュアコンテキストで実行されているかどうかを、isSecureContext
ブール値(WindowOrWorkerGlobalScope
上で定義)を確認することで判定できます。
2.2.3. セキュア・非セキュアコンテキスト
HTML現行標準は環境がセキュアコンテキストか非セキュアコンテキストかを定義しています。これは他の仕様で利用される主要な仕組みです。
グローバルオブジェクトが与えられた場合、仕様はその関連設定オブジェクト(これは環境である) がセキュアコンテキストかどうかを確認できます。
3. アルゴリズム
3.1. origin は潜在的に信頼できるか?
潜在的に信頼できるオリジンとは、ユーザーエージェントが一般的に安全にデータを配信していると信頼できるオリジンのことです。
このアルゴリズムは、従来の意味で認証・暗号化されていなくても、特定のホストやスキーム、オリジンを潜在的に信頼できるものとして扱います。特に、ユーザーエージェントは file
URLを潜在的に信頼できるものとして扱うべきです。原則としてユーザーエージェントはローカルファイルを信頼できないものとして扱うこともできますが、実行時にユーザーエージェントが利用できる情報に鑑みると、リソースは安全にディスクからユーザーエージェントへ転送されているように見えます。また、開発者がアプリケーションを公開前に作成する際にも、こうしたリソースを信頼できるものとして扱うことは利便性があります。
ただし、この開発者寄りの利便性にはリスクが伴います。セキュリティを重視するユーザーエージェントは、file
を除外するようより厳密な信頼判定を行うこともあります。
逆に、ユーザーエージェントは app:
や chrome-extension:
など、あらかじめ信頼できると判断できるベンダー固有のURLスキームにもこの信頼を拡張することができます(詳細は § 7.1
パッケージアプリケーション を参照)。
origin(origin)が与えられた場合、以下のアルゴリズムは適切に
"Potentially Trustworthy
" または "Not Trustworthy
" を返します。
-
もし origin が 不透明オリジンであれば、"
Not Trustworthy
" を返す。 -
アサート: origin は タプルオリジンである。
-
もし origin の スキームが "
https
" または "wss
" なら、"Potentially Trustworthy
" を返す。注: これは a priori 認証済みURL の概念と類似しています([MIX] 参照)。
-
もし origin の ホストが CIDR表記
127.0.0.0/8
または::1/128
に一致する場合、"Potentially Trustworthy
" を返す。 -
ユーザーエージェントが [let-localhost-be-localhost] の名前解決規則に準拠していて、以下のいずれかが真の場合:
この場合、"
Potentially Trustworthy
" を返す。注: 詳細は § 5.2 localhost を参照してください。
-
もし origin の スキームが "
file
" なら、"Potentially Trustworthy
" を返す。 -
もし origin の スキームがユーザーエージェントが認証済みと判断するものであれば、"
Potentially Trustworthy
" を返す。注: 詳細は § 7.1 パッケージアプリケーション を参照してください。
-
もし origin が信頼できるオリジンとして設定されていれば、"
Potentially Trustworthy
" を返す。注: 詳細は § 7.2 開発環境 を参照してください。
-
"
Not Trustworthy
" を返す。
注: origin の ドメインや ポートは、セキュアコンテキストかどうかの判定には影響しません。
3.2. url は潜在的に信頼できるか?
潜在的に信頼できるURLとは、作成者からコンテキストを継承するもの(about:blank
、about:srcdoc
、data
)、またはそのオリジンが潜在的に信頼できるオリジンであるものです。
URLレコード(url)が与えられた場合、以下のアルゴリズムは適切に"Potentially Trustworthy
"または"Not Trustworthy
"を返します:
-
もし url が "
about:blank
" または "about:srcdoc
" なら、"Potentially Trustworthy
" を返す。 -
もし url の スキームが "
data
" なら、"Potentially Trustworthy
" を返す。 -
§ 3.1 origin は潜在的に信頼できるか? を url の オリジンに対して実行した結果を返す。
注:
blob:
URLのオリジンは、それが作成されたコンテキストのオリジンです。したがって、信頼できるオリジンで作成されたblobは自身も潜在的に信頼できます。
4. 脅威モデルとリスク
このセクションは規範的ではありません。
4.1. 脅威モデル
認証されていないオリジンに権限を付与することは、ネットワーク攻撃者が存在する場合、実質的にあらゆるオリジンに権限を付与することと同等です。インターネットの現状では、ネットワーク攻撃者が存在すると仮定する必要があります。一般的に、ネットワーク攻撃者は2つのクラスに分類されます:パッシブ型とアクティブ型です。
4.1.1. パッシブネットワーク攻撃者
「パッシブネットワーク攻撃者」とは、通信の流れを監視できるが、この仕様が対象とするレイヤーで通信内容を改変する能力がない、または改変しないことを選択する当事者を指します。
このようなネットワークの監視は「通信者の意図を、当事者の同意なしに覆す」ものであり、「最も悪意ある行為者への防御を行うならば、善意とみなされる行為者による監視も許してはならない」ものです。 [RFC7258] したがって、この文書で定義されるアルゴリズムは、アプリケーション層でのデータのプライバシーを守る仕組みを必要とし、単なる完全性のみでは不十分です。
4.1.2. アクティブネットワーク攻撃者
「アクティブネットワーク攻撃者」は「パッシブネットワーク攻撃者」としての全ての能力に加え、ネットワークを通過するデータを改変・遮断・再送できる能力を持ちます。こうした能力は、公共の無線ネットワークに参加する、または提供するデバイスの侵害から、金融目的でトラフィック操作を行うインターネットサービスプロバイダー([VERIZON] や [COMCAST] などの最近の例)、個人・組織・全人口を標的とする直接的なセキュリティ・プライバシー侵害の意図を持つ者まで、様々なレベルの潜在的な敵対者に利用可能です。
4.2. 祖先リスク
secure context
アルゴリズムは、あるコンテキストが安全かどうかを判断するために、その全ての祖先を辿ります。では、iframe
内に安全に配信されたドキュメントを、それ自体安全とみなさないのはなぜでしょうか?
簡単に言えば、このモデルは悪用を可能にしてしまうからです。Chrome の [WEBCRYPTOAPI] 実装は、API
を安全なコンテキストに限定する初期の試みでしたが、コンテキストの祖先を確認しませんでした。API を安全に配信されたリソースにロックするだけで十分と考えられていました。しかし、Netflix のような事業者が
iframe
や postMessage()
を用いたシムを構築し、API
を非セキュアなコンテキストに公開しました。この制限は、非セキュアなアクセスを少し遅らせただけで、アクセス自体は完全に防げませんでした。
この文書のアルゴリズムは、secure context から非セキュアなコンテキストを完全に隔離するものではありません(§ 5.1 不完全な隔離 で議論)。しかし、祖先チェックは、認証・機密性・完全性の保証に対して、かなり堅牢な保護を提供します。
4.3. 非セキュアコンテキストに関連するリスク
ユーザーのセキュリティやプライバシーに明確な影響を与えるウェブプラットフォームの機能は、上記の脅威に対抗するために secure contexts でのみ利用可能であるべきです。非セキュアコンテキストで利用可能な機能は、ネットワーク攻撃者にこれらの能力を公開するリスクがあります:
- 個人情報、認証情報、支払い手段などの機密データを読み書きできる能力。[CREDENTIAL-MANAGEMENT-1] は、機密データを扱う API の一例です。
- ユーザーのデバイスのセンサーからの入力(カメラ、マイク、GPSなど特に重要ですが、加速度計のような一見危険ではないセンサーも含む)を読み書きできる能力。[GEOLOCATION-API] や [MEDIACAPTURE-STREAMS] は、センサー入力を利用する機能の歴史的な例です。
- ユーザーがアクセス可能な他のデバイスの情報にアクセスできる能力。[DISCOVERY-API] や [WEB-BLUETOOTH] が良い例です。
- 一時的または永続的な識別子を利用してユーザーを追跡できる能力。識別子は一定期間後にリセットされるもの(例:
window.sessionStorage
)、ユーザーが手動でリセットできるもの(例:[ENCRYPTED-MEDIA]、Cookie [RFC6265]、[IndexedDB])、またユーザーが簡単にはリセットできないハードウェア特性を含みます。 - オリジンにブラウジングセッションをまたいで持続する状態を導入できる能力。[SERVICE-WORKERS] が好例です。
- ユーザーエージェントのネイティブ UI を操作し、ユーザーのコンテキスト認識に関わる情報を削除・隠蔽・改変できる能力。[FULLSCREEN] が良い例です。
- ユーザーの許可が必要な機能を導入できる能力。
このリストは網羅的ではありませんが、仕様を書く・実装する際に考慮すべきリスクの種類を示しています。
注: 機能自体を secure contexts に制限することは重要ですが、同様にネットワークデータにアクセスできる新しいネットワークアクセス機構や汎用的な関数など、そうした情報を扱う施設も同様に機微なものとして忘れてはなりません。
5. セキュリティに関する考慮事項
5.1. 不完全な隔離
secure context
の定義は、同一オリジンの「セキュア」なビューと「非セキュア」なビューを完全に隔離するものではありません。localStorage
/sessionStorage
の内容、storage
イベント、BroadcastChannel
など、ますます特殊なメカニズムによる情報流出は依然として可能です。
5.2. localhost
[RFC6761]
のセクション6.3は、localhost.
および .localhost.
内の名前の解決を特別なものとし、ローカルリゾルバがそれらを特別に扱うべき/扱ってもよいことを示唆しています。良くも悪くも、リゾルバはこれらの提案を無視し、様々な状況で
localhost
をネットワークに送信することがあります。
このような不確実性を踏まえ、ユーザーエージェントは、potentially
trustworthy origins として localhost 名を扱ってもよいですが、その場合は [let-localhost-be-localhost] で示された localhost
名解決ルール(localhost
が非ループバックアドレスに決して解決されないことの保証)にも準拠している必要があります。
6. プライバシーに関する考慮事項
secure context の定義自体はプライバシーへの影響を持ちません。しかし、他のプライバシーに重要な影響を持つ機能が、完全性・認証性・機密性に関する特定の保証を可能にするコンテキストへと自らをロックする仕組みを提供します。
プライバシーの観点から、仕様作成者は定義する機能に対して secure contexts を要求することを推奨します。
7. 実装に関する考慮事項
7.1. パッケージアプリケーション
パッケージアプリケーションをサポートするユーザーエージェントは、ユーザーエージェントによって認証された内容を持つ特定のURLスキームを「セキュア」とみなしてもよいです。例えば、FirefoxOSのアプリケーションリソースは
scheme コンポーネントが app:
のURLで参照されます。同様に、Chrome
の拡張機能やアプリは chrome-extension:
スキームで動作します。これらは信頼できるオリジンと合理的に見なすことができます。
7.2. 開発環境
ループバック以外のホストでステージングサーバーを実行する開発者をサポートするために、ユーザーエージェントは § 3.1 オリジンは信頼できるか? が通常 "Not Trustworthy
"
を返す場合でも、ユーザーが特定のオリジンのセットを信頼できるものとして設定できるようにしてもよいです。
7.3. 新機能の制限
このセクションは規範的ではありません。
新しい機能の仕様を書く際には、著者や編集者は secure contexts へのチェックで機微なAPIを保護することを推奨します。 例えば、以下のような記述が良いアプローチとなるでしょう:
-
current settings object が secure
context で ない場合:
- [ここに適切な処理を挿入:Promise を
SecurityError
で reject する、エラーコールバックを呼ぶ、許可リクエストを拒否する等]
- [ここに適切な処理を挿入:Promise を
また、敏感なAPIを [SecureContext
]
属性でガードし、secure contexts にのみ公開することもできます。
[SecureContext ]interface SensitiveFeature {Promise <double >getTheSecretDouble (); }; // Or:interface AnotherSensitiveFeature { [SecureContext ]void doThatPowerfulThing (); };
7.4. レガシー機能の制限
このセクションは規範的ではありません。
上記のリストには、現在非セキュアチャネルでウェブに提供されている既存の機能も含まれています。こうしたレガシー機能もできるだけ速やかに secure context を要求するよう修正することを推奨します。[W3C-PROCESS]
-
その機能が広く実装されていない場合は、仕様を即座に 修正 し、secure contexts の制限を含めることを推奨します。
-
その機能が広く実装されているが、まだ広く利用されていない場合は、既存の実装に § 7.3 新機能の制限 で述べたようなチェックを追加し、仕様も 修正 することで、速やかに secure contexts への制限を推奨します。
-
その機能が広く利用されている場合は、既存機能を廃止することを推奨します。仕様には本書の制限に準拠しないことを明記し、準拠した新バージョンの提供と既存利用者の移行計画を策定するべきです。
7.4.1. 例:Geolocation
[GEOLOCATION-API] は、非セキュアなサイトで広く実装・利用されている具体例です。合理的な移行案は次のようになるでしょう:
-
仕様の修正により、secure context であることを
getCurrentPosition()
およびwatchPosition()
のアルゴリズム実行前にチェックするようにします。current settings object が secure context でない場合はアルゴリズムを中断し、
errorCallback
にPERMISSION_DENIED
のcode
を渡して呼び出します。 -
ユーザーエージェントは、非セキュアコンテキストでAPIを無効にする明確な意図を特定日に発表し、開発者に警告する(例:コンソールメッセージなど)べきです。
-
「旗日」に向けて、ユーザーエージェントは段階的な廃止計画を発表し、サイト作者がコード修正の必要性を認識できるようにし、ユーザーの安全も確保します。計画には以下のいずれかまたは全てを含めてもよいでしょう:
-
非セキュアオリジンへの持続的な許可付与の禁止
-
非セキュアオリジンへのAPI精度の低下(例:常に都市レベルのデータのみ返す)
-
リスクをユーザー・サイト作者に通知するUI変更
-
-
8. 謝辞
この文書は主に Chrome セキュリティチームの [POWERFUL-NEW-FEATURES] に関する作業を基にしています。Chris Palmer、Ryan Sleevi、David Dorwin は特に積極的に関与しました。また、Anne van Kesteren、Jonathan Watt、Boris Zbarsky、Henri Sivonen からも非常に有益なフィードバックをいただきました。