UIR

upgrade-insecure-requests 指令 (CSP)

[67] CSP指令 upgrade-insecure-requests は、そのページに関する fetch で http: を https: に書き換えること (格上げ (upgrade) ) を指示するものです。

[68] HTTP要求の Upgrade-Insecure-Requests: ヘッダーは、クライアントが本 CSP指令に対応していることを示すものです。

仕様書

[69] 本機能は W3C WebAppSec WG で Mike West らにより開発された仕様書 Upgrade Insecure Requests (非保安要求の格上げ、 UIR) で規定されています。

意味

[71] CSP指令 upgrade-insecure-requests は、本来 http: URL で指定され素のHTTP で fetch するべきところを https: に書き換え HTTPS で fetch するよう、 Webブラウザーに指示するものです。

[72] 10年代半ば、インターネットのプロトコルが平文から TLS ベースへと移行することを迫られる中、既存の http: 前提の Webサイトの HTTPS への移行のために Webサイト中の http: URL をすべて書き換えなければ Mixed Content 制約に抵触することが問題となりました。 例えば script 要素で http: の絶対URLが指定されていると、 そのままでは HTTPS 化できません。そのため、あまりメンテナンスされなくなった Webページや本文を編集したくない歴史的な文書などの Webサイトは HTTPS に移行するのが困難でした。

[73] そこで導入された本機能を使うと、Webページの文書自体は編集せずとも HTTPヘッダーを追加するだけで、 Mixed Content 制約の検査の前に http: URL をWebブラウザーに読み替えさせることができます。

[74] ただし Mixed Content 制約を実装して本機能を実装しない旧来の Webブラウザーに対して HTTPS でWebサイトを提供すると、 CSP指令は単に無視されますから、 URL の書き換えが行われず、 Webサイトは壊れてしまいます。そこで本機能に対応した Webブラウザーは HTTP要求に Upgrade-Insecure-Requests: 1 ヘッダーを追加することになっています。サーバーはこのヘッダーがある時だけ HTTPS で本機能を利用し、そうでない時は従来通り素のHTTP で Webサイトを提供できます。

[75] この HTTPヘッダーによるサーバー側での分岐は、すべての Webブラウザーが本 CSP指令に対応さえすれば、不要になると思われます。 Webブラウザーは多くの要求で Upgrade-Insecure-Requests: 1 ヘッダー分の余計な転送が必要となりますが、いずれはそれも要らなくなるかもしれません。 (現状でもできるだけ削減するために HSTS の情報が使われています。) 一方で CSP指令は HTTPS に移行した Webサイトが今後も意図通り動作し続けるために、 Webブラウザーが恒久的に対応し続ける必要があります。

[76] CSP指令 upgrade-insecure-requests は、その文書内の画像、スクリプト、ワーカー、 XHR アクセスなどで http: を https: に読み替えさせます。 WebSocket アクセスでは ws: を wss: に読み替えさせます。

[78] CSP指令 upgrade-insecure-requests は、その文書からの navigate (ハイパーリンクやフレームなど) のうち、同じ起源へのものや、フォーム提出について http: を https: に読み替えさせます。

[79] このCSP指令の効果はフレーム内にも及びます。 フレーム内でこれを解除することはできません。

用語

[25] 本仕様書では次の用語が定義されています。

プロトコル

[59] 本仕様書では次のプロトコル要素が定義されています。

格上げ

[24] URL scheme を https や wss に書き換えた時、要求を格上げ (upgrade) したといいます >>22。

[39] 格上げは、 Mixed Content や CSP の検査よりも前に行われます。

fetch 参照。

非保安要求ポリシー

[27] 環境設定群オブジェクトと閲覧文脈は、 非保安要求ポリシー (insecure requests policy) を持ちます >>26。

[28] その値は、 「格上げする (Upgrade) 」、 「格上げしない (Do Not Upgrade) 」のいずれかです >>26。 既定値は「格上げしない」です >>26。

[41] この値は、 Content-Security-Policy: upgrade-insecure-requests で設定されます。

[29] この値は、 navigate 以外の要求やフォームの提出において、 http: → https: の書き換えを行うかどうかの判断に使われます。

[30] navigate では非保安navigate格上げ集合が参照されます。

[61] この値は閲覧文脈の作成や新しい文書オブジェクトの作成で設定されることがあります。 すなわち、フレーム外の文書の指定は、フレーム内の文書にも適用されます。

[62] ワーカーの作成時には、作成元の値が引き継がれます。

[64] クライアントについて非保安要求を格上げするべきか (Should insecure requests be upgraded for client?) は、 次のように決まります >>65。

  1. [137] クライアントが有責文書を持つなら、
    1. [138] クライアントの有責文書の非保安要求ポリシーを返します。
  2. [139] それ以外で、クライアントが有責閲覧文脈を持つなら、
    1. [140] クライアントの有責閲覧文脈の非保安要求ポリシーを返します。
  3. [141] それ以外なら、
    1. [142] 「格上げしない」を返します。

[66] これは main fetch や WebSocket接続の確立で参照されます。

Content-Security-Policy: upgrade-insecure-requests

[32] CSP の指令 upgrade-insecure-requests は、被保護資源の非保安要求を格上げするべきことを示します >>31。

[33] 値は、空です >>31。

[34] Content-Security-Policy: ヘッダーで使うことができます >>31。 <meta http-equiv=Content-Security-Policy> での利用も禁止されていません。 Content-Security-Policy-Report-Only: ヘッダーでも禁止はされていませんが意味はありません >>31。

[77] http: での利用も禁止されておらず、 処理も https: の場合と変わらないようです。

[35] enforce は、次のようにします >>31。

  1. [36] 被保護資源の現職設定群オブジェクトの非保安要求ポリシーを、 「格上げ」に設定します。
  2. [37] 被保護資源の現職設定群オブジェクトの非保安navigate格上げ集合に、 被保護資源の URL のホストとポートの組を挿入します。

[38] monitor は、何もしません >>31。

[40] upgrade-insecure-requests と block-all-mixed-content を併用するべきではありません >>31。 両方が適用される場合、前者が優先されます。

Upgrade-Insecure-Requests: ヘッダー

[43] Upgrade-Insecure-Requests: ヘッダーは、 クライアントがサーバーに対して暗号化されて認証された応答を望んでいること、 CSP upgrade-insecure-requests 指令を処理できることを示すものです >>42。

[80] 本ヘッダーは fingerprinting vector です。

構文

[44] このヘッダーの値は、 1 です >>42。 upgrade-insecure-requests に対応していることを示します。

  1. 1

[45] 未対応の時は、このヘッダー自体を指定しません。

文脈

[49] 利用者エージェントは、 a priori insecure URL への要求で Upgrade-Insecure-Requests: ヘッダーを送信しなければなりません >>42。

[51] 利用者エージェントは、 potentially secure URL でそのホストが preloadable HSTS host でなければ、要求で Upgrade-Insecure-Requests: ヘッダーを送信しなければなりません >>42。

[53] 利用者エージェントは、 potentially secure URL でそのホストが preloadable HSTS host なら、要求で定期的に Upgrade-Insecure-Requests: ヘッダーを送信するべきです >>42。

[54] 例えば、 max-age で示された期限間近の時だけ送信することもできますし、 少ない割合でのみ送信することもできます。 >>42

[56] prelodable HSTS host は HSTS安全だとわかっているので格下げ (>>55) は不要ですが、 max-age の満期前に HSTS 状態を更新する必要があり、 サーバーは Upgrade-Insecure-Requests: をその合図として使うことができます。 >>42

[58] それ以外の場面 (応答など) での利用は禁止こそされていませんが、意味はありません。

処理

[55] サーバーは、素の HTTP の要求で Upgrade-Insecure-Requests: ヘッダーがあれば、要求された資源の potentially secure representation にリダイレクトするべきです >>42。

[50] サーバーは、 a priori insecure URL への要求で Upgrade-Insecure-Requests: ヘッダーがあれば、 upgrade-insecure-requests が必要なページへの HTTP の要求を HTTPS への要求へと格上げできます >>42。

[57] サーバーは、HTTPS の要求で Upgrade-Insecure-Requests: ヘッダーがあれば、要求のホストが HSTS安全か条件付きHSTS安全の場合、 応答に Strict-Transport-Security: ヘッダーを含めるべきです >>42。

[60] サーバーは、HTTPキャッシュを考慮して Vary: ヘッダーに Upgrade-Insecure-Requests を追加する必要があるかもしれません。

関連

[70] HTTPヘッダー Upgrade: とは無関係です。

歴史

[46] Upgrade-Insecure-Requests: ヘッダーは、 当初 Prefer: ヘッダーの値として導入することが検討されていましたが、 HTTPキャッシュの効率に悪影響を及ぼす虞があるとして、 断念されました >>42。

[47] 次に HTTPS: ヘッダーとすることが提案され、 実際に Chrome に実装されましたが、 (驚くべきことに) HTTPS か素の HTTP かの判断に影響を及ぼすサーバーが少なからず見つかったため、 ヘッダー名が改められました。

[48] そんなサーバーはきっと何か恐ろしい脆弱性があるに違いありませんが...

[1] UPGRADE: Describe a 'return=secure-representation' preference. · e524850 · w3c/webappsec ( 版) https://github.com/w3c/webappsec/commit/e524850dd6d8862712b18b43b9754ce951960cbf

[2] Re: UPGRADE: Feature detection? (Mike West 著, 版) https://lists.w3.org/Archives/Public/public-webappsec/2015Feb/0280.html

[3] Re: [upgrade] return=secure-representation (Mike West 著, 版) https://lists.w3.org/Archives/Public/public-webappsec/2015Mar/0086.html

[4] UPGRADE: Change to 'Prefer: https', which is (hopefully) not horrible ho... · a0aa404 · w3c/webappsec ( 版) https://github.com/w3c/webappsec/commit/a0aa404a84a0eca2040246fcd805980461d327ae

[5] UPGRADE: 'tls' is shorter than 'https'. · 29d07a9 · w3c/webappsec ( 版) https://github.com/w3c/webappsec/commit/29d07a99aebebd02f40a2daa9feb8425c36c5c21

[6] UPGRADE: Rename the header from `Prefer: tls` to `HTTPS: 1`. · d7d9fc0 · w3c/webappsec ( 版) https://github.com/w3c/webappsec/commit/d7d9fc0e16573455cf17d562eaff9667096e6489

[7] Integrate with UPGRADE. Fixes https://www.w3.org/Bugs/Public/show_bug.cg... · whatwg/fetch@fd90b5a ( 版) https://github.com/whatwg/fetch/commit/fd90b5afd0ff09284c2a3cd093c577d17ce06898

[8] Upgrade Insecure Requests ( 版) http://www.w3.org/TR/2015/WD-upgrade-insecure-requests-20150424/

[10] UPGRADE: 'HTTPS' header causing compatibility issues. (Mike West 著, 版) https://lists.w3.org/Archives/Public/public-webappsec/2015Jun/0075.html

[11] Re: UPGRADE: 'HTTPS' header causing compatibility issues. (Mike West 著, 版) https://lists.w3.org/Archives/Public/public-webappsec/2015Jul/0052.html

[12] UPGRADE: Rename 'HTTPS: 1' to 'Upgrade-Insecure-Requests: 1'. · w3c/webappsec@eeac392 ( 版) https://github.com/w3c/webappsec/commit/eeac3922418bfa6cb254071c74ddd962ee418c80

[13] Re: UPGRADE: 'HTTPS' header causing compatibility issues. (Mike West 著, 版) https://lists.w3.org/Archives/Public/public-webappsec/2015Jul/0108.html

[14] UPGRADE: Ugly first stab at a strawman. · 56a27a2 · w3c/webappsec ( 版) https://github.com/w3c/webappsec/commit/56a27a20bef8a3f8f9cf29fecf49b8163eb85afd

[15] Upgrade Insecure Requests ( ( 版)) http://www.w3.org/TR/2015/WD-upgrade-insecure-requests-20150226/

[16] Upgrade Insecure Requests ( ( 版)) https://w3c.github.io/webappsec/specs/upgrade/

[17] 1139297 – Implement CSP upgrade-insecure-requests directive ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=1139297

[18] 776278 – Auto Upgrade Insecure Requests from Secure Context ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=776278

HSTS plus upgrade-insecure-requests is the way to go.

[19] Upgrade Insecure Requests ( 版) https://w3c.github.io/webappsec-upgrade-insecure-requests/

[21] w3c/webappsec-upgrade-insecure-requests ( 版) https://github.com/w3c/webappsec-upgrade-insecure-requests

[20] Upgrade Insecure Requests ( ( 版)) http://www.w3.org/TR/2015/CR-upgrade-insecure-requests-20151008/

[81] Allow upgrades from explicitly insecure expressions · w3c/webappsec-csp@0e81d81 ( 版) https://github.com/w3c/webappsec-csp/commit/0e81d81b64c42ca3c81c048161162b9697ff7b60

[82] [UPGRADE] passive mixed content breakage with the current variant of upgrade-insecure-requests (Peter Eckersley 著, 版) https://lists.w3.org/Archives/Public/public-webappsec/2015Dec/0055.html

[83] 1243586 – Implement Upgrade-Insecure-Requests HTTP Request Header Field ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=1243586

[84] Chrome だと fetch される https: からHTTPリダイレクトで http: に飛ばされる時、 UIR が適用されないように見えます。(Fetch Standard によればその場合も UIR が適用されるべきだと思われますが...)

[85] Proposal for a MIX Level 2 roadmap. (Mike West著, ) https://lists.w3.org/Archives/Public/public-webappsec/2017Oct/0013.html

[86] webappsec-mixed-content/proposed-level-2-roadmap.md at master · mikewest/webappsec-mixed-content () https://github.com/mikewest/webappsec-mixed-content/blob/master/proposed-level-2-roadmap.md

[87] Add MIX level 2 skeleton by estark37 · Pull Request #21 · w3c/webappsec-mixed-content () https://github.com/w3c/webappsec-mixed-content/pull/21