HTTPQUERY
日本語

Strict-Transport-Security

使い方

Strict-Transport-Security ヘッダーは、HTTP Strict Transport Security(HSTS)の背後にある仕組みです。ブラウザがセキュアな接続でこのヘッダーを受け取ると、ブラウザはそのディレクティブを記録し、指定されたドメインに対する以降のすべての HTTP リクエストを自動的に HTTPS へ引き上げます。セキュアな接続が利用できない場合、ブラウザは平文の HTTP にフォールバックするのではなく、アクセス自体を拒否します。

このヘッダーは HTTPS で配信された場合にのみ尊重されます。平文の HTTP で配信されたレスポンスに含まれる Strict-Transport-Security は無視されます。ネットワーク経路上の攻撃者がヘッダーを挿入したり改変したりできるからです。

このヘッダーは 3 つのディレクティブを受け付けます。max-age、includeSubDomains、preload です。

max-age

max-age ディレクティブは必須です。値は、そのドメインに対して HTTPS を強制することをブラウザが記憶する秒数を指定します。本番環境でよく使われる値は 63072000(2 年)です。max-age=0 を設定すると、ブラウザのキャッシュから HSTS のエントリが直ちに消去されます。

includeSubDomains

includeSubDomains ディレクティブは、HTTPS の強制をそのホストのすべてのサブドメインへ拡張します。このディレクティブがなければ、HSTS はレスポンスの示す正確なドメインにのみ適用されます。includeSubDomains を加えることで、攻撃者が平文 HTTP のサブドメインを悪用して cookie を設定したりトラフィックをリダイレクトしたりするのを防げます。

preload

preload ディレクティブは HSTS の仕様の一部ではありません。ブラウザベンダーは HSTS のプリロードリストを管理しており、preload ディレクティブはそのリストへの登録を望むというドメイン所有者の意思を示します。ドメインがプリロードリストに載ると、ブラウザは最初の接続から HTTPS を強制するため、最初の Strict-Transport-Security ヘッダーを受け取るまでの脆弱な期間がなくなります。プリロードリストへの申請には、少なくとも 1 年(31536000 秒)の max-age と includeSubDomains ディレクティブが必要です。

例

すべてのサブドメインにわたって 2 年間 HTTPS を強制し、プリロードの要件も満たすサーバーです。

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

主ドメインのみに 6 か月間 HSTS を設定する最小限の構成です。

Strict-Transport-Security: max-age=15768000

max-age を 0 に戻して HSTS のエントリを消去します。移行作業やテストの際に役立ちます。

Strict-Transport-Security: max-age=0

トラブルシューティング

HSTS の問題は、ブラウザがポリシーをローカルにキャッシュするため、サーバーを変更した後も解消しない接続の失敗やリダイレクトループとして現れがちです。

長い max-age で HSTS を有効にした後に締め出される。ブラウザが HSTS ポリシーを記録すると、すべてのリクエストが自動的に HTTPS へ引き上げられます。max-age が切れるか、ユーザーが手動で HSTS のエントリを消去するまで、HTTP に戻すことはできません。Chrome では chrome://net-internals/#hsts を開き、「Delete domain security policies」の欄にドメインを入力してエントリを削除します。Firefox ではブラウザを終了し、プロファイルフォルダー内の SiteSecurityServiceState.txt を編集して、そのドメインの行を削除します。

includeSubDomains によるサブドメインの不具合。includeSubDomains を加えると、社内ツール、ステージングサーバー、有効な証明書を持たないレガシーなサービスを含むすべてのサブドメインで HTTPS が強制されます。このディレクティブを有効にする前に、すべてのサブドメインが信頼された TLS 証明書を配信していることを確認してください。サブドメインが壊れた場合は、includeSubDomains を外し、max-age=0 でヘッダーを再配信してキャッシュされたエントリを消去します。

プリロードリストからの削除に数か月かかる。HSTS のプリロードリストはブラウザのリリースに同梱されるため、削除には hstspreload.org での申請、次のリスト更新の待機、そしてその更新がブラウザのバージョンアップを通じてユーザーへ届くまでの待機が必要です。この手続きには数か月かかります。preload は長期的なコミットメントとして扱い、申請前に HTTPS への完全な対応を確認してください。

平文 HTTP で送られた HSTS ヘッダーは無視される。暗号化されていない接続で届いたレスポンスの Strict-Transport-Security ヘッダーを、ブラウザは破棄します。このヘッダーが効力を持つのは HTTPS のレスポンスに限られます。curl -sI https://example.re | grep -i strict で、HTTPS のレスポンスにヘッダーが含まれていることを確認してください。

HSTS 有効化後の混在コンテンツエラー。HSTS はページを HTTPS へ引き上げますが、埋め込まれたリソースが依然として http:// の URL を参照していると、混在コンテンツの警告やブロックが発生します。すべてのリソースの URL(画像、スクリプト、スタイルシート、API のエンドポイント)を点検し、https:// またはプロトコル相対のパスを使うよう参照を更新してください。残っているハードコードされた HTTP の URL については、CSP の upgrade-insecure-requests ディレクティブが自動的に処理します。

証明書の更新失敗によるサイト全体の締め出し。HSTS で保護されたドメインで証明書が期限切れや不正になると、ユーザーが回避する手段のない致命的な失敗になります。ブラウザはサイトの表示を拒否し、「それでも続行」の選択肢も提示しません。証明書の更新を自動化し(Let’s Encrypt の certbot は cron ジョブでこれを処理します)、証明書の有効期限を監視してください。期限の少なくとも 14 日前にアラートが出るよう設定します。