結論(HTTPSからHTTPへ降格しない)
HTTPSからHTTPへ降格しないとは、HTTPSで始まった通信が、301/302/303/307/308のリダイレクトとLocationヘッダーによって http:// のURLへ移されないことです。途中で一度でもHTTPに落ちると、その区間は盗聴・改ざんが可能になり、以降のページを攻撃者が差し替える足がかりになります。最終的にHTTPSのページに着いても安全ではないため、すべての転送先をHTTPSに固定する必要があります。
この記事のポイント
- 降格(ダウングレード)とは、HTTPSの応答が3xxリダイレクトで http:// のURLへ転送する状態です。
- 主な原因は、TLS終端の背後にあるアプリがX-Forwarded-Protoを見ずにhttp://のLocationを組み立てることです(末尾スラッシュ補完やログイン後の戻り先で頻発)。
- 途中のHTTP区間ではSecure属性のないCookieやクエリ文字列が平文で流れ、応答も改ざんされ得ます。
- HSTSは初回訪問者や別ホストへの転送には効かないため、降格リダイレクトの代わりにはなりません。
- セキュリティAIチェッカーは入力URLのリダイレクト列にHTTPS→HTTPの遷移があれば×(重み5・critical)と判定します。
| 診断項目名 | HTTPSからHTTPへ降格しない |
|---|---|
| 項目ID | transport.redirect-downgrade |
| 分類 | 通信の暗号化(HTTPS・TLS・HSTS) |
| 重大度・配点の重み | 最重要(critical) 重み 5 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V12.2.1(Level 1「外部向け HTTP サービスとの通信はすべて TLS を使い、安全でない通信や非暗号化通信へフォールバックしないこと」)、OWASP ASVS 5.0.0 V3.4.1(Level 1、HSTS)、OWASP WSTG-CRYP-01(HTTP から HTTPS へのリダイレクト)、WSTG-CONF-07(HSTS)、WSTG-CRYP-03(非暗号化チャネルでの機微情報送信)、RFC 6797(HSTS)第7.2節、RFC 9110 第15.4節(3xx リダイレクト)、CWE-319(重要な情報の平文での送信) |
HTTPSからHTTPへ降格しないとは
HTTPSからHTTPへ降格しないとは、HTTPSで始まった通信が、リダイレクト(301/302/303/307/308 と Location ヘッダー)によって http:// のURLへ移されない状態のことです。HTTPSからHTTPへ移されることを「降格(ダウングレード)」と呼びます。
利用者がHTTPSでアクセスしていても、途中で一度でもHTTPに落ちれば、その区間の通信は盗聴・改ざんが可能になり、以降のページを攻撃者が差し替える足がかりになります。セキュリティAIチェッカーはこの項目で、診断対象URLを取得する際のリダイレクト列に、HTTPS→HTTPの遷移が含まれていないかを確認します。重大度はcritical、重み5です。
降格リダイレクトの例
# 降格が起きている例(1回目の応答の Location が http://)
HTTP/1.1 301 Moved Permanently
Location: http://www.city.example.lg.jp/soshiki/
HTTP/1.1 301 Moved Permanently
Location: https://www.city.example.lg.jp/soshiki/
HTTP/1.1 200 OK
最終的にHTTPSのページに着いていても、間にある http:// の区間が降格です。
「HTTPからHTTPSへ転送」との違い
「HTTPからHTTPSへ転送」は、HTTPでアクセスした利用者をHTTPSへ昇格させる転送があるかを見る項目です。本項目は逆向きで、HTTPSで始まった通信がHTTPへ戻されないかを見ます。HTTPSで配信されているかどうか自体は「HTTPSで配信されている」で評価します。
HTTPSからHTTPへの降格はなぜ起きるのか
降格が起きる典型的な原因
- TLS終端の背後にあるアプリが、自分をHTTPだと思っている:ロードバランサー・CDN・リバースプロキシでTLSを終端し、オリジンへHTTPで転送している構成では、アプリやCMSが
X-Forwarded-Protoを見ずにhttp://の絶対URLで Location を組み立てることがあります。末尾スラッシュの補完(/kurashi→/kurashi/)や、ログイン後の戻り先で頻発します。 - CMSのサイトURL設定が http のまま:WordPress の
siteurl/homeなど、基準URLがhttp://に設定されていると、正規化リダイレクトでHTTPに戻されます。 - ホスト名の正規化:
https://city.example.lg.jp/→http://www.city.example.lg.jp/のように、www付与の転送先だけが http で書かれている。 - 古いページ移転設定:旧ドメインや旧パスの転送ルールに
http://が直書きされている。
ブラウザの挙動とHSTSの関係
- 転送先ホストにHSTSが有効(過去にHSTSヘッダーを受け取っている、またはプリロード済み)であれば、ブラウザは
http://への転送を内部的にhttps://へ書き換えます。しかし、初回訪問者やHSTS未設定のホスト、別ホストへの転送では保護されません。 - RFC 6797 第7.2節は、HSTSホストが非セキュアな通信でリクエストを受けた場合、HTTPSへの恒久リダイレクトを返すべき(SHOULD)としています。HTTPSからHTTPへ戻す動作は、この考え方と正反対です。
- 降格したHTTP応答の中身は改ざん可能なため、攻撃者は sslstrip のような手法で、以降のリンクをすべてHTTPのまま保つことができます。
- 3xxリダイレクトの意味は RFC 9110 第15.4節で定められています。
降格リダイレクトについてよくある誤解
- 「最終的にHTTPSのページに着くから問題ない」:誤りです。途中のHTTP区間で、Cookie(Secure属性なし)やクエリ文字列が平文で流れ、応答も改ざんされ得ます。
- 「HSTSを設定したから降格リダイレクトは無害」:不十分です。HSTSは一度HTTPSで受け取るまで効かず、別ホストへの転送には効きません(HSTSの設定は「HSTSが設定されている」で確認します)。
HTTPSからHTTPへ降格しないの診断基準(セキュリティAIチェッカー)
取得方法
- 入力されたURLに対して GET を送り、301/302/303/307/308 かつ Location ヘッダーがある場合に、最大4回まで転送をたどります(リダイレクト上限を超えた場合は診断全体がエラー)。
- たどったURL列を「入力URL → 転送先1 → 転送先2 …」の順に記録し、隣り合う2つのURLの間で
https:からhttp:へ変わった箇所があるかを調べます。
判定条件
| 判定 | 条件 | 根拠文の例 |
|---|---|---|
| 対象外(na) | リダイレクト列の中に https: のURLが1つもない(入力も最終もHTTP) | HTTPSの区間がないため降格判定の対象外(HTTPS化そのものは「HTTPSで配信されている」項目で×) |
| × 要改善(fail) | https: のURLの直後に http: のURLがある | HTTPSからHTTPへ移るリダイレクトを確認 |
| ○ 問題なし(pass) | それ以外 | 取得したリダイレクト列にHTTPS→HTTP降格はない |
得点への影響
| 判定 | 得点 |
|---|---|
| ○ 問題なし(pass) | 5点(重み5) |
| × 要改善(fail) | 0点 |
| 対象外(na) | 採点から除外 |
HTTPのみで配信しているサイトでは本項目が対象外となり、HTTPS関連の他項目で減点されます。
判定範囲の限界
- 確認するのは、入力URLの取得時に通ったリダイレクト列だけです。巡回した他ページのリダイレクトや、フォーム送信後の転送、ログイン後の戻り先は対象外です。
<meta http-equiv="refresh">や JavaScript(location.href = "http://...")による遷移は、HTTPの3xxではないため検出しません。- HSTSによる内部書き換えは再現しません(初回訪問者と同じ条件で判定します)。
自治体サイトでの判定例
| リダイレクト列 | 判定 |
|---|---|
https://www.city.example.lg.jp/ が200を返す | ○ |
http://city.example.lg.jp/ → https://www.city.example.lg.jp/ | ○(HTTP→HTTPSは昇格) |
https://www.city.example.lg.jp/soshiki → http://www.city.example.lg.jp/soshiki/ → https://www.city.example.lg.jp/soshiki/ | ×(途中で降格) |
http://www.town.example.jp/ がHTTPのまま200 | 対象外(HTTPS化が先決) |
HTTPSからHTTPへ降格するとどんなリスクがあるか
- 盗聴:HTTP区間のリクエストに含まれるCookie(Secure属性なし)、URLパラメータ(検索語、受付番号など)が、公衆無線LANなどで第三者に見られます(CWE-319:重要な情報の平文での送信)。
- 改ざん・なりすまし:攻撃者がHTTP応答を差し替え、偽の申請フォームやマルウェア配布ページへ誘導できます。自治体サイトは住民の信頼が高いため、フィッシングの踏み台として悪用されると被害が大きくなります。
- HTTPSの固定化の失敗:降格後のページ内リンクがすべてHTTPに書き換えられると、利用者はその後もHTTPのまま閲覧し続けます。
- 単純な原因で影響が全体に及ぶ:本項目は「転送設定の誤り」という単純な原因で起きる一方、影響が通信全体に及ぶため、criticalとしています。
降格リダイレクトの確認方法と修正方法(Apache・nginx・IIS・Next.js)
まず原因箇所を特定する
# リダイレクト列をすべて表示(-L で追跡、-I でヘッダーのみ)
curl -sIL https://www.city.example.lg.jp/soshiki | grep -iE '^(HTTP/|location:)'
# 末尾スラッシュなし・www なしなど複数パターンを確認
for u in https://city.example.lg.jp/ https://www.city.example.lg.jp/soshiki https://www.city.example.lg.jp/index.html; do
echo "== $u"; curl -sIL "$u" | grep -iE '^(HTTP/|location:)'
done
Apache(.htaccess)
RewriteEngine On
# HTTP → HTTPS(転送先は必ず https を明記)
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# ホスト名の正規化も https で
RewriteCond %{HTTP_HOST} ^city\.example\.lg\.jp$ [NC]
RewriteRule ^ https://www.city.example.lg.jp%{REQUEST_URI} [R=301,L]
mod_dir の末尾スラッシュ補完が http:// を返す場合は、ServerName https://www.city.example.lg.jp のようにスキームを含めて指定するか、プロキシ背後なら UseCanonicalName と X-Forwarded-Proto の扱いを見直します。
nginx
server {
listen 80;
server_name city.example.lg.jp www.city.example.lg.jp;
return 301 https://www.city.example.lg.jp$request_uri;
}
server {
listen 443 ssl;
server_name www.city.example.lg.jp;
absolute_redirect off; # 自動リダイレクトを相対 Location にする
location / {
proxy_pass http://app_backend;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect http:// https://; # バックエンドが返した http:// を書き換え
}
}
IIS(web.config、URL Rewrite モジュール)
<rewrite>
<rules>
<rule name="HTTPS only" stopProcessing="true">
<match url="(.*)" />
<conditions><add input="{HTTPS}" pattern="off" /></conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
Next.js・CMS・PHP
- Next.js の
redirects()では、destinationを相対パスかhttps://で記述します。独自ミドルウェアでnew URL(path, request.url)から転送先を組み立てる場合は、プロキシ背後でrequest.urlがhttp://にならないか、実際の Location ヘッダーを curl で確認します。 - WordPress は管理画面の「WordPress アドレス」「サイトアドレス」を
https://にし、リバースプロキシ背後ではwp-config.phpでX-Forwarded-Protoを見て$_SERVER['HTTPS'] = 'on'を設定します。 - PHPの自作コードで
header("Location: http://...")と書いている箇所を検索し、相対パスかhttps://に直します。
サイトを壊さないための注意点(ガードレール)
- HTTPS化と同時にHSTS(まず短い max-age から)を設定し、降格が残っていても再訪問者を保護します。有効期間の決め方は「HSTSの有効期間」を参照してください。
- 転送ルールの変更後は、トップページだけでなく、末尾スラッシュなし、
index.html付き、wwwなし、旧ドメインなど複数の入口を curl で確認します。 - CDNのキャッシュに古い301応答が残ることがあります。設定変更後はキャッシュを削除してから確認します。
よくある質問(FAQ)
最終的にHTTPSのページに着くなら、途中でHTTPを経由しても問題ないのでは?
問題があります。途中のHTTP区間では、Secure属性のないCookieやクエリ文字列が平文で流れ、応答そのものも改ざんされ得ます。攻撃者はその区間で偽ページを返したり、以降のリンクをHTTPのまま保ったりできます。
HSTSを設定していれば降格リダイレクトは無害ですか?
不十分です。HSTSは一度HTTPSでヘッダーを受け取るまで効かず、HSTSが記録されていない別ホストへの転送にも効きません。転送先にHSTSが有効ならブラウザは内部的にhttpsへ書き換えますが、初回訪問者は保護されません。
HTTPS→HTTPの降格リダイレクトはなぜ起きるのですか?
代表的な原因は、ロードバランサーやCDNでTLSを終端し、オリジンへHTTPで転送している構成で、アプリやCMSが http:// の絶対URLでLocationを組み立てることです。CMSのサイトURL設定がhttpのまま、www付与の転送先だけがhttp、古い移転ルールにhttp://が直書きされている場合にも起きます。
降格リダイレクトがあるかを確認するには?
curl -sIL でリダイレクトをたどり、HTTPステータス行とLocationヘッダーだけを表示します。トップページだけでなく、末尾スラッシュなし、index.html付き、wwwなし、旧ドメインなど複数の入口を確認してください。
nginxで末尾スラッシュの自動リダイレクトがhttpになる場合の対処は?
absolute_redirect off で自動リダイレクトのLocationを相対パスにします。バックエンドがhttp://のLocationを返す場合は proxy_redirect http:// https:// で書き換え、X-Forwarded-Proto https をバックエンドへ渡します。
meta refreshやJavaScriptによる遷移も診断されますか?
されません。セキュリティAIチェッカーが確認するのは、入力URLの取得時に通ったHTTPの3xxリダイレクト列だけです。meta refresh、JavaScriptでの遷移、フォーム送信後やログイン後の戻り先は対象外のため、手動で確認してください。
HTTPのみで配信しているサイトはどう判定されますか?
リダイレクト列にHTTPSのURLが1つもない場合は対象外(na)です。HTTPS化そのものは「HTTPSで配信されている」などの別項目で評価され、そちらで減点されます。
この項目を含む127項目を、URLを入れるだけで無料診断します。
参考資料
- OWASP ASVS 5.0.0 V12 Secure Communication(V12.2.1)
- OWASP ASVS 5.0.0 V3 Web Frontend Security(V3.4.1)
- OWASP WSTG-CRYP-01 Testing for Weak Transport Layer Security
- OWASP HTTP Strict Transport Security Cheat Sheet
- RFC 6797 HTTP Strict Transport Security(第7.2節)
- RFC 9110 HTTP Semantics(第15.4節 Redirection 3xx)
- nginx absolute_redirect ディレクティブ
- nginx proxy_redirect ディレクティブ
- CWE-319 Cleartext Transmission of Sensitive Information