upgrade-insecure-requests の使い方:安全でないリクエストを送信前に HTTPS へ

upgrade-insecure-requests は、ブラウザが送信する前に http:// を https:// へ書き換える CSP ディレクティブです。ヘッダーの付け方、安全でない URL の洗い出し、移行順序、HSTS が必要な場面をまとめます。

クロールとインデックス9分で読めます2492 回閲覧
upgrade-insecure-requests の使い方:安全でないリクエストを送信前に HTTPS へ

upgrade-insecure-requests は、ブラウザがリクエストを送る前に http:// の URL を https:// へ書き換える Content-Security-Policy のディレクティブです。レスポンスヘッダーを 1 行追加すれば、ページ内の http:// のサブリソースはすべて https:// で取得されます。これは書き換えであり、修復ではありません。安全な URL が応答しなければ、リクエストは失敗し、HTTP へのフォールバックはありません。HSTS の代わりにもなりません。別ホストへのリンクは対象外だからです。

upgrade-insecure-requests が変えるもの

このディレクティブは、混合コンテンツのブロックより前に動きます。W3C の仕様では、メカニズムが「a priori」に安全でないリソースリクエストを「before fetching them」の段階で安全な転送へアップグレードし、書き換えは混合コンテンツや CSP のチェックより前に起きると説明されています。そのため、アップグレードされたリクエストは混合コンテンツとして報告されません(Upgrade Insecure Requests、W3C Candidate Recommendation、2015 年 10 月 8 日、2026-11-03 閲覧)。MDN も同じ挙動を説明し、2018 年 4 月以降 Baseline として広く利用可能としています(MDN、2026-11-03 閲覧)。

価値はこのタイミングにあります。ブラウザは安全でないリクエストをそもそも送らないので、混合コンテンツのブロックが捕まえるものが残りません。

リクエストアップグレードHTTPS 失敗時
同一サイトの画像、http://される画像が失敗、HTTP 再試行なし
第三者スクリプト、http://されるスクリプトが失敗、HTTP 再試行なし
同一サイトへのリンクされるページが開かない、代替なし
別ホストへのリンクされないブラウザは HTTP のまま
HTTP しかないリソースされるリクエスト自体が失敗

見落とされやすいのは 4 行目です。同一サイトへのナビゲーションはアップグレードされますが、別ホストへのナビゲーションはアップグレードされません(同じ仕様の 1.2.2 節、2026-11-03 閲覧)。だからこのディレクティブは HSTS の代わりになりません。

upgrade-insecure-requests の追加方法

レスポンスヘッダー 1 行で足ります。安全でない URL を含み得るすべての HTML レスポンスに付けてください。

Content-Security-Policy: upgrade-insecure-requests

ホスティング側でヘッダーを変更できない場合は、meta 要素を使います。ただし、その meta を含む文書だけが対象です。

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

block-all-mixed-content は一緒に書かないでください。MDN はこのディレクティブを非推奨としており、W3C の仕様では upgrade-insecure-requests が先に評価されるため、両方あると block-all-mixed-content は実質何もしません(MDN、2026-11-03 閲覧)。どちらか一方にしてください。

適用する前に安全でない URL を洗い出す

まず数を数えます。次の 2 つのコマンドは 1 分で終わり、確認できるリストを作ります。すべては見つかりません。JavaScript が組み立てる URL と CSS の中の URL は、2 つ目のコマンドには現れません。

# 1. すでにディレクティブを送っているか
curl -sI https://example.com | grep -i '^content-security-policy'

# 2. まだ http:// のリソースはどれか
curl -s https://example.com \
  | grep -oE '(src|href)="http://[^"]+' \
  | sort -u

2 つ目のコマンドは、トップページだけでなく、多くのページを生成するテンプレートに対して実行します。チェックアウト、記事、ランディングページでは、読み込む第三者スクリプトが違うことが多いからです。修正後も混合コンテンツの警告が出る場合は、診断方法が混合コンテンツの修正(英語)にあります。

レポート専用モードで一度デプロイすると、実際のリストが得られます。ブラウザは何も書き換えずに違反レポートだけを送るので、ソースコードの走査で見つけた URL と突き合わせられます。

Content-Security-Policy-Report-Only: upgrade-insecure-requests; report-uri /csp-reports

report-uri は古い仕組みです。report-to は新しい設定方法ですが、すべてのホスティングで互換ではありません。今回、各 CDN でのレポート配信は検証していません。空のレポートを「問題なし」の証拠にする前に、自分のエンドポイントに届いているか確認してください。

このディレクティブが止まる場所

構文より大事な制限が 3 つあります。

  1. 第三者へのナビゲーション。 別ホストへの http:// リンクはアップグレードされません。訪問者は HTTP でページを離れ、このディレクティブでは止められません。
  2. HTTPS がない場合。 代替はありません。アップグレード後の URL が HTTPS で応答しなければ、リクエストは失敗し、ページはそのリソースを失います。
  3. HSTS。 Strict-Transport-Security の代わりにはなりません。HSTS は今後の訪問と最初のナビゲーションを守り、このディレクティブは現在のページが出すリクエストを守ります。

仕様は WebSocket も別扱いしています。ディレクティブが適用される場合、安全でない ws:// 接続は wss:// にアップグレードされます(同仕様 5 節、2026-11-03 閲覧)。実際の WebSocket エンドポイントは検証していないので、これは仕様に書かれている挙動として記録し、測定結果としては扱いません。

クローラーについては答えのない問いが残ります。Googlebot や AI クローラーがこのディレクティブに従うかは検証していません。現在のブラウザと同じようにレンダリングするクローラーなら書き換えを受けるはずですが、どのクローラーにも測定値はなく、推測を結果として書くつもりはありません。

ページを壊さない移行順序

何年も http:// を手書きしてきたサイトで、私ならこの順番で進めます。

  1. テンプレートを棚卸しする。 トップページだけでなく重要なページで 2 つのコマンドを実行し、出力をファイルに残します。
  2. 自分で制御できるものを直す。 同一サイトの画像、フォント、スクリプトを先に HTTPS へ移します。この失敗は目に見え、1 回のデプロイで直せます。
  3. 第三者を 1 社ずつ確認する。 HTTPS の URL を依頼します。用意がない場合は、適用前にリソースを差し替えるか削除します。
  4. 1 回のクロール周期だけレポート専用で動かす。 レポートと棚卸しを突き合わせます。レポートにあって棚卸しにない URL は、ソース走査が取りこぼしたものです。
  5. 適用して検証する。 適用ヘッダーに切り替え、ネットワークパネルを開いて再読み込みし、http:// のリクエストが残っていないことを確認します。HSTS は別の判断として残します。

成果物はヘッダーの 1 行ではなく、棚卸し表とレポートの突き合わせです。ヘッダーは 10 秒で付けられます。棚卸しが仕事です。

静かに失敗する 3 つのパターン

どれも初回読み込みで静かに壊れ、2 つは CDN の問題に見えます。

  1. 第三者が HTTPS に対応する前に適用する。 リクエストは書き換えられ、相手のサーバーは 443 で応答せず、リソースが消えます。HTTP への再試行はありません。
  2. トップレベルのリンクも対象だと思う。 パートナーサイトへの http:// リンクは、訪問者を HTTP のまま送り出します。その役割は HSTS です。
  3. 2 つの CSP ディレクティブを重ねる。 block-all-mixed-content は非推奨で、アップグレードのディレクティブがあると何もしません。2 行のほうが安全に見えますが、正しい設定は 1 行です。

使わないほうがよい場合

ページが HTTP しかない第三者スクリプトに依存しているなら、適用すると初回読み込みでそのスクリプトが壊れます。最初の訪問をダウングレード攻撃から守りたいなら、道具は HSTS で、max-age と preload を別途決める必要があります。安全でない URL が数個だけなら、直接直してください。このディレクティブは、今週直せない長い尾のためにあります。

アップグレード失敗がどれだけのトラフィック損失になるかは、私たちには言えません。どのリソースが壊れるか、それがなくてもページが何をするかに依存します。ヘッダーではなくページを測ってください。

よくある質問

HSTS と同じものですか?

いいえ。HSTS は、そのホストへの今後のリクエストで HTTPS を使うようブラウザに伝えます。upgrade-insecure-requests は現在のページが出す安全でないリクエストを書き換えます。W3C の仕様は両者を分けて扱い、このディレクティブが HSTS の代わりにならないと明記しています(2026-11-03 閲覧)。

混合コンテンツの警告は消えますか?

ほとんどの混合コンテンツのリクエストは送信前に書き換えられるため、平文では出ていきません。HTTPS 版が存在しないリソースは直せません。そのリクエストは失敗します。

meta タグでも動きますか?

動きますが、その meta を含む文書だけです。レスポンスヘッダーは設定したすべての HTML レスポンスを覆い、meta は自分のページだけを覆います。

Upgrade-Insecure-Requests リクエストヘッダーとは何ですか?

別のヘッダーです。ブラウザは Upgrade-Insecure-Requests: 1 を送り、アップグレードできることを伝えます。サーバーはこれを使って安全でないリクエストに 307 リダイレクトを返せます。能力検出であり、適用のディレクティブではありません。

CDN でも使えますか?

CDN がレスポンスヘッダーを通過させれば使えます。デプロイ後に curl -sI で 1 つ確認してください。今回、各 CDN のヘッダー処理は検証していないので、自分のエッジで確認してください。

Googlebot は従いますか?

Googlebot も AI クローラーも検証していません。自分のログか、レンダリングを伴う取得で確認してから依存してください。

次のステップ

ページが HTTPS だけで読み込まれるようになったら、次はクローラーがあなたと同じ HTML を受け取っているかです。AI クローラーが実際に受け取るものを確認し、リクエストとレンダリング結果を並べたいときは QueryWin のページビューを使ってください。

収録: QueryWinガイド · レベル2

upgrade-insecure-requests の使い方:安全でないリクエストを送信前に HTTPS へ