HSTSとは
HSTS(HTTP Strict Transport Security)は、ブラウザーにHTTPSだけでウェブサイトへ接続させ、HTTPでは接続させないウェブセキュリティ機構です。ブラウザーがHSTSヘッダーを受け取ると、今後のリクエストを自動的にHTTPSへ昇格し、利用者が http://. と明示的に入力しても平文HTTP接続を拒否します。
HSTSが重要な理由
有効なSSL証明書があっても、https:// を使わない接続では脆弱性が残ります。
SSLストリッピング攻撃
1. 利用者が「example.com」と入力する(https:// なし)
2. 攻撃者が最初のHTTPリクエストを傍受する
3. 攻撃者がHTTPSへ中継し、利用者にはHTTPを見せる
4. 利用者は安全だと思うが、攻撃者にはすべてが見える
HSTSはブラウザーが最初のHTTPリクエストを送らないようにして、この攻撃を防ぎます。
HSTSの利点
- ダウングレード攻撃を防ぐ: HTTPへのフォールバックができない
- ユーザーのブックマークを守る: 古いHTTPブックマークもHTTPSになる
- 混在コンテンツをなくす: サブリソースもHTTPSへ強制する
- 性能を向上させる: HTTPからHTTPSへのリダイレクトが不要になる
HSTSヘッダーの構文
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
ディレクティブ
| ディレクティブ | 説明 |
|---|---|
| max-age | HSTSを記憶する秒数(31536000は1年) |
| includeSubDomains | すべてのサブドメインにHSTSを適用 |
| preload | ブラウザーのプリロードリストへの登録に同意 |
HSTSの実装
Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Cloudflareの設定
Cloudflareの管理画面で、SSL/TLS → Edge Certificates → HTTP Strict Transport Securityを有効化します。これは安全な接続を必須にする設定です。
Express.js
const helmet = require('helmet');
app.use(helmet.hsts({
maxAge: 31536000,
includeSubDomains: true,
preload: true
}));
HSTSプリロードリスト
HSTSプリロードリストは、HTTPSでのみアクセスすべきドメインをブラウザーにハードコードした一覧です。最初のHTTPリクエストに伴う脆弱性までなくします。
プリロードの要件
1. 有効なSSL証明書
2. すべてのHTTPをHTTPSへリダイレクトする
3. 次のHSTSヘッダーを設定する:
- max-ageは少なくとも31536000(1年)
- includeSubDomainsディレクティブ
- preloadディレクティブ
4. すべてのサブドメインがHTTPSに対応する
プリロードリストへの申請
1. 要件を確認する: hstspreload.orgで確認する
2. ドメインを申請する: hstspreload.orgにドメインを入力する
3. 登録を待つ: ブラウザー更新に数週間から数か月かかる
プリロードの注意
プリロードは実質的に恒久的です。リストから削除するには数か月かかり、ブラウザーの更新も必要です。すべてのサブドメインが無期限にHTTPSへ対応できると確信できる場合だけ申請してください。HSTSの確認
ブラウザーの開発者ツール:1. 開発者ツールを開き、Networkタブを選ぶ
2. サイトを読み込む
3. レスポンスヘッダーでStrict-Transport-Securityを確認する
curlを使う:curl -I https://example.com | grep -i strict
DomScanを使う:
curl "https://domscan.net/v1/health?domain=example.com"
# Reports hasHSTS in security details
プリロード状態:
hstspreload.orgでドメインがプリロード済みか確認します。
HSTS導入戦略
フェーズ1: 短いmax-age
短いmax-ageで開始してテストします。
Strict-Transport-Security: max-age=300
問題が起きても、利用者側のキャッシュは5分間だけです。
フェーズ2: 期間を延ばす
HTTPSがどこでも機能することを確認したら:
Strict-Transport-Security: max-age=86400
フェーズ3: サブドメインを追加する
すべてのサブドメインがHTTPSに対応したら:
Strict-Transport-Security: max-age=2592000; includeSubDomains
フェーズ4: 完全導入とプリロード
数か月安定して運用できたら:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
その後、プリロードリストへ申請します。
HSTSでよくある問題
HTTPSに対応しないサブドメイン: includeSubDomainsによってそのサブドメインが壊れる 開発環境: 本番でキャッシュされたHSTSがローカル開発を壊す CDNやプロキシのヘッダー: 中継システムがHSTSヘッダーを削除していないことを確認する 混在コンテンツ: すべてのリソースがHTTPSでなければならない。HSTSは埋め込まれたHTTPリソースを修正しないHSTSは機密データを扱うすべてのウェブサイトに不可欠であり、HTTPSサイト全般に強く推奨されます。