Featured image of post HSTS (HTTP Strict Transport Security) によるHTTPS強制接続の確実な設定方法Featured image of post HSTS (HTTP Strict Transport Security) によるHTTPS強制接続の確実な設定方法

HSTS (HTTP Strict Transport Security) によるHTTPS強制接続の確実な設定方法

HSTS(HTTP Strict Transport Security)によるHTTPS強制接続の確実な設定方法を解説。初回接続時のMITM攻撃を防ぐ仕組み、サブドメインへの展開方法、ブラウザのHSTSプリロードリストへの登録手順まで網羅的に紹介します。

初期リクエストの問題点

HTTPS は接続確立後のトラフィックを暗号化しますが、HTTP で行われる最初のリクエストは平文のまま送信されます。同じネットワーク上の攻撃者はこの最初のリクエストを傍受し、SSL ストリッピング攻撃 によってセッション全体を HTTP にダウングレードできます。

HTTP Strict Transport Security(HSTS)はこの問題を解決します。ブラウザが HSTS ヘッダーを受け取ると、以後すべての HTTP リクエストを 自動的に HTTPS にアップグレード し、証明書が無効な場合は接続を拒否します。

HSTS の仕組み

サーバーは HTTPS レスポンスで Strict-Transport-Security ヘッダーを送信します:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
ディレクティブ説明
max-age=<秒>HTTPS のみを使用するようブラウザが記憶する期間
includeSubDomainsすべてのサブドメインにポリシーを適用
preloadブラウザのプリロードリストへの登録を希望

ブラウザはこのヘッダーを受け取ると:

  1. ドメインの http:// リンクをすべて https:// に書き換え
  2. TLS ハンドシェイクが失敗したり証明書が無効な場合は接続を拒否
  3. max-age で指定された期間ポリシーをキャッシュ

サーバーでの設定

NGINX

server {
    listen 443 ssl;
    ssl_certificate /etc/ssl/certs/example.pem;
    ssl_certificate_key /etc/ssl/private/example.key;

    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}

always パラメータにより、エラーページでもヘッダーが送信されます。

Apache

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Cloudflare

Cloudflare のダッシュボードから HSTS を有効化できます:SSL/TLS > Edge Certificates > HTTP Strict Transport Security。プリロードや includeSubDomains の切り替えはワンクリックです。

Express/Node.js

const helmet = require("helmet");
app.use(helmet.hsts({
  maxAge: 31536000,
  includeSubDomains: true,
  preload: true
}));

HSTS プリロードリスト

max-age はユーザーが少なくとも一度サイトに訪問した後にのみ機能します。ブラウザに組み込まれた HSTS プリロードリスト(Chrome、Firefox、Safari、Edge)は、常に HTTPS を使用すべきドメインをハードコードし、初期リクエストの脆弱性を根本的に排除します。

登録手順:

  1. サイトが preload を含む有効な HSTS ヘッダーを返すことを確認
  2. hstspreload.org にアクセス
  3. ドメインを送信

プリロード登録の要件:

要件詳細
有効な証明書すべてのサブドメインで TLS 対応
max-age最低 31536000(1年)
includeSubDomains必須
preloadヘッダーに含める
リダイレクトすべての HTTP → HTTPS リダイレクト

警告: プリロード登録は実質的に永続的です。一度受理されると、ドメインをリストから簡単に削除できません。

HSTS 設定のテスト

いくつかのツールで設定を検証できます:

# curl でヘッダー確認
curl -sI https://example.com | findstr -i "strict-transport"

# Security Headers: https://securityheaders.com
# SSL Labs: https://www.ssllabs.com/ssltest/analyze.html?d=example.com
# HSTS プリロード状態の確認
curl -s https://hstspreload.org/api/v2/check?domain=example.com

よくある問題

問題影響解決策
max-age が短すぎるポリシーが頻繁に期限切れ最低1年に設定
includeSubDomains がないサブドメインが保護されないディレクティブを追加
HTTP のみのサイトで HSTS を配信ヘッダーが無視されるHTTPS でのみ配信
混合コンテンツブラウザが安全でないリソースをブロックすべての http:// 参照を監査
準備なしのプリロード恒久的な HTTPS 必須化まず max-age=0 でテスト

開発時の HSTS 解除

キャッシュされた HSTS ポリシーをクリアする方法:

  • Chrome: chrome://net-internals/#hsts → Delete domain
  • Firefox: ドメインの閲覧履歴を消去
  • Safari: 環境設定から Web サイトデータを消去

開発時は max-age=0 でポリシーを取り消せます:

Strict-Transport-Security: max-age=0

まとめ

HSTS は、初回訪問以降の HTTPS 利用を強制し、SSL ストリッピングやダウングレード攻撃を防ぐ基本的なセキュリティヘッダーです。max-age=31536000includeSubDomains、オプションで preload を設定して完全な保護を実現しましょう。セキュリティチェッカーで設定を検証し、開発中は HSTS キャッシュを適宜クリアしてください。