2026年7月16日
2026年7月16日
HSTS を解除する方法(max-age=0 の送り方とブラウザ側の削除)
HSTS(HTTP Strict Transport Security)を解除するには、ヘッダーを消すのではなく、HTTPS のまま Strict-Transport-Security: max-age=0 を送ってブラウザに記憶を消させるのが正しい手順です。ヘッダーを単に削除しても、一度 HSTS を受け取ったブラウザは max-age の期限まで HTTPS を強制し続けるからです。この記事では、HSTS がどこで設定されているかの探し方、サーバー側の解除手順、プリロードリストに登録している場合の扱い、自分のブラウザに残った HSTS を消す方法までを説明します。
解除する前に:本当に解除が必要か考える
HSTS を解除したいと考える理由は、たいてい次のどれかです。
includeSubDomainsを付けたところ、HTTPS に対応していないサブドメイン(社内システム、古いメール管理画面など)が開けなくなった。- 証明書の更新に失敗し、ブラウザが警告画面から先に進ませてくれない。
- サイトを別のサーバーへ移す途中で、一時的に HTTP で確認したい。
このうち2つ目と3つ目は、HSTS を解除するより、証明書を直したり、HTTPS のまま確認できるようにしたりするほうが早く、安全です。HSTS は、公衆 Wi-Fi などで HTTP 接続を狙った通信の乗っ取りを防ぐための仕組みで、外すと訪問者がその防御を失います。1つ目のケースでも、まずはそのサブドメインを HTTPS に対応させられないかを検討してください。それでも解除が必要な場合に、以下の手順に進みます。
HSTS の仕組みと、解除に時間がかかる理由
HSTS は、サーバーが HTTPS の応答に次のようなヘッダーを付けることで有効になります。
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
ブラウザはこのヘッダーを受け取ると、「このドメインには max-age 秒のあいだ HTTPS でしか接続しない」と記憶します。上の例なら1年間です。重要な点は次の2つです。
- 記憶はブラウザ側にある:サーバーのヘッダーを消しても、すでに記憶したブラウザの設定は残ります。期限が来るか、新しい指示を受け取るまで変わりません。
- HTTPS で受け取ったヘッダーしか有効にならない:HTTP の応答に付けた HSTS ヘッダーは無視されます。そのため、解除の指示(
max-age=0)も HTTPS で送る必要があります。
つまり、解除とは「HTTPS を正常に動かしたまま、max-age=0 を訪問者のブラウザに受け取ってもらう」作業です。一度もサイトを再訪しない人には指示が届かないため、その人のブラウザでは元の max-age が切れるまで HSTS が残ります。
手順1:HSTS ヘッダーがどこで付いているか特定する
まず、現在どのようなヘッダーが返っているかを確認します。
curl -sI https://example.com/ | grep -i strict-transport-security
ヘッダーが2行以上表示される場合は、複数の場所で設定されています。HSTS ヘッダーを付けている可能性がある場所は次のとおりです。上から順に確認すると見つけやすくなります。
- CDN・ロードバランサー:Cloudflare などの CDN には HSTS を有効にする設定があります。CDN で付けている場合、オリジンのサーバー設定を変えても効きません。
- Web サーバーの設定:Nginx の
add_header Strict-Transport-Security ...、Apache のHeader always set Strict-Transport-Security ...。.htaccessに書かれていることもあります。 - WordPress のプラグイン:SSL 化を補助するプラグインやセキュリティ系プラグインの中には、HSTS を有効にする設定を持つものがあります。設定項目の名称や位置はバージョンで変わります(2026年10月現在)。
- テーマや独自コード:
functions.phpや mu-plugin でheader()やsend_headersフックを使って付けている場合があります。
サーバー上の設定ファイルを検索すると、見落としを減らせます。
sudo grep -rni 'strict-transport-security' /etc/nginx/ /etc/apache2/ /etc/httpd/ 2>/dev/null
grep -rni 'strict-transport-security' /var/www/ --include='*.php' --include='.htaccess'
パスは環境に合わせて変えてください。
手順2:max-age=0 を HTTPS で送る
ヘッダーを付けている場所を見つけたら、削除するのではなく、値を max-age=0 に書き換えます。変更前に設定ファイルのバックアップを取っておきます。
Nginx
add_header Strict-Transport-Security "max-age=0" always;
Nginx の add_header は、location ブロックなど内側で別の add_header を書くと外側の設定が引き継がれない仕様です。server ブロックで書き換えても、location 側に古い HSTS の指定が残っていればそちらが返ります。手順1の grep で見つかった箇所はすべて直します。
Apache
Header always set Strict-Transport-Security "max-age=0"
WordPress のプラグインで設定していた場合
プラグインの HSTS 設定をオフにすると、ヘッダーそのものが出なくなるだけで max-age=0 は送られないことがあります。その場合は、プラグインの設定をオフにしたうえで、Web サーバー側で一定期間 max-age=0 を送るようにします。
反映後、もう一度確認します。
sudo nginx -t && sudo systemctl reload nginx # Apache なら apachectl configtest と reload
curl -sI https://example.com/ | grep -i strict-transport-security
max-age=0 だけが1行返れば、サーバー側の変更はできています。
手順3:解除の指示が行き渡るまで HTTPS を維持する
max-age=0 を受け取れるのは、HTTPS でサイトを再訪したブラウザだけです。そのため、すぐに HTTP に戻したり証明書を外したりしてはいけません。少なくとも、それまで設定していた max-age の期間(1年なら1年)は HTTPS を正常に動かし、max-age=0 を送り続けるのが理想です。
includeSubDomains を付けていた場合は、親ドメイン(例:example.com)の応答で max-age=0 を送る必要があります。サブドメインだけで送っても、親ドメインの記憶は消えません。訪問者が親ドメインをあまり訪れない構成なら、サブドメインのページから親ドメインの画像などを1つ読み込ませて、親ドメインの応答を受け取る機会を作る方法もあります。
手順4:プリロードリストに登録している場合
ヘッダーに preload を付けて hstspreload.org から登録していた場合、ドメインはブラウザに組み込まれたリストに載っています。この場合はサーバーの設定を変えるだけでは解除できません。
- HSTS ヘッダーから
preloadを外す(上記のmax-age=0への変更で同時に外れます)。 - hstspreload.org の削除申請ページから、ドメインの削除を申請する。
- 削除がブラウザのリストに反映され、そのバージョンのブラウザが利用者に行き渡るのを待つ。
削除はブラウザのリリースを通じて反映されるため、数か月単位の時間がかかります。プリロード登録の解除は「すぐには戻せない」前提で考えてください。
自分のブラウザに残った HSTS を消す方法
サーバー側の解除とは別に、作業者が自分のブラウザで確認したいときは、ブラウザに残った HSTS の記録を手動で消せます。これは自分の端末だけに効く方法で、訪問者の端末には影響しません。
- Chrome / Edge:アドレスバーに
chrome://net-internals/#hsts(Edge はedge://net-internals/#hsts)を入力し、「Delete domain security policies」の欄にドメインを入れて削除します。プリロードリストに載っているドメインはここでは消せません。 - Firefox:履歴からそのサイトを右クリックし、「このサイトの履歴を消去」に相当する項目を選ぶと HSTS の記録も消えます(表記はバージョンで異なります)。
- Safari:サイトのデータや履歴を削除すると消える場合がありますが、OS やバージョンによって挙動が違うため、消えたかどうかは再度アクセスして確認してください。
なお、HSTS と並べて語られることの多い CORS(オリジン間リソース共有)は、別オリジンからのリソース取得を許可する仕組みで、HSTS とは目的も設定も別物です。CORS のエラーを解消するために HSTS を外しても効果はありません。
まとめ
- HSTS の解除は、ヘッダーを消すのではなく、HTTPS のまま
Strict-Transport-Security: max-age=0を送るのが正しい手順です。 - ヘッダーは CDN・Web サーバー・プラグイン・独自コードのどこで付いているかを
curl -sIと grep で特定し、すべて書き換えます。 - 解除の指示は再訪したブラウザにしか届かないため、それまでの max-age の期間は HTTPS を維持します。
includeSubDomainsの場合は親ドメインで送ります。 - プリロード登録済みなら hstspreload.org から削除を申請し、反映に数か月かかる前提で計画します。
- 作業者のブラウザは
chrome://net-internals/#hstsなどで個別に記録を消せますが、訪問者側の解除にはなりません。