HSTS(Strict-Transport-Security)
ブラウザに「このドメインは常に HTTPS でアクセスせよ」と記憶させ、HTTP へのダウングレード攻撃や、ユーザーの打ち間違い(http://)を防ぎます。
何が起きるか
一度 HSTS を受け取ったブラウザは、以後そのドメインへのアクセスを自動的に HTTPS に強制します(期限内)。
代表的ディレクティブ
max-age=<秒>: 強制期間(例: 31536000=1年)includeSubDomains: サブドメインにも適用preload: ブラウザのプリロードリスト登録を意図(運用が慎重)
例(本番で HTTPS 完全移行済み前提)
Strict-Transport-Security: max-age=31536000; includeSubDomains
注意点
- HTTPS が完全に安定してから入れる。入れると、期限内は原則 HTTP で戻せません。
includeSubDomains/preloadは影響範囲が大きい(特に別運用のサブドメインがある場合)。
CSP(Content-Security-Policy)
XSS(クロスサイトスクリプティング)や不正なリソース読込を抑止するために、読み込んでよいスクリプト/CSS/画像/API 先などをホワイトリストで制御します。
何が起きるか
ポリシーに違反するリソース(例:未許可ドメインの JS)がブロックされます。XSS が仕込まれても “実行されにくく” なります。
よく使うディレクティブ
default-src: 既定の許可元script-src: JS の許可元(最重要)style-src: CSS の許可元img-src: 画像の許可元connect-src: fetch/XHR/WebSocket 先(API、GA4 等)font-src,frame-src,object-src,base-uri,form-actionframe-ancestors: 埋め込み(iframe)許可元(XFO の上位互換)
導入の定石
Content-Security-Policy-Report-Onlyで違反を観測- 例外を洗い出してからブロックモードへ
例(かなり強めの雛形。実際はGA/フォント/CDN等に合わせ調整)
Content-Security-Policy:
default-src 'self';
base-uri 'self';
object-src 'none';
frame-ancestors 'none';
form-action 'self';
img-src 'self' data: https:;
script-src 'self';
style-src 'self';
connect-src 'self'
注意点
- 既存サイトは インライン script/style や外部 CDN が多く、いきなり厳格にすると壊れがち。
nonce/hashを使う設計が王道です。 frame-ancestorsはクリックジャッキング対策に強力。
XFO(X-Frame-Options)
ページが第三者サイトに iframe で埋め込まれることを制限し、クリックジャッキングを抑止します。
値
DENY: 埋め込み全面禁止SAMEORIGIN: 同一オリジンのみ許可ALLOW-FROM <uri>: 旧仕様で非推奨・非対応ブラウザ多い
例
X-Frame-Options: DENY
補足(実務上の結論)
- 現代は CSP の
frame-ancestorsが推奨(より柔軟・標準的)。 - ただし互換性のために、
frame-ancestorsと XFO を併用することもあります。
Referrer-Policy
リンク遷移や外部リソース取得時に送られる Referer(参照元URL)を、どの程度相手に伝えるかを制御します。URL にはパスやクエリが含まれるため、情報漏えい対策にもなります。
よく使う値
no-referrer: 一切送らないorigin: オリジン(https://example.com)のみ送るsame-origin: 同一オリジンにだけフルで送るstrict-origin-when-cross-origin(実質推奨・デフォルトに近い)- 同一オリジン:フル
- クロスオリジン:origin のみ
- HTTPS→HTTP などダウングレード時:送らない
例
Referrer-Policy: strict-origin-when-cross-origin
Cache-Control
ブラウザや CDN、プロキシに対して、キャッシュの可否・期限・再検証の要否を指示します。パフォーマンスと最新性のバランスを支配する重要ヘッダーです。
代表的ディレクティブ
public/private: 共有キャッシュ(CDN等)可否max-age=<秒>: キャッシュ有効期間s-maxage=<秒>: 共有キャッシュ向け max-age(CDN)no-store: 保存禁止(最も強い。機密向け)no-cache: “キャッシュしてよいが毎回再検証”must-revalidate: 期限切れは必ず再検証immutable: 期限内は再検証しない(指紋付き静的資産向け)stale-while-revalidate,stale-if-error: 体感改善(対応環境あり)
典型パターン
HTML(動的ページ): 早めに更新される前提
Cache-Control: no-cache, private
ログインなど機密:
Cache-Control: no-store
静的資産(CSS/JS/画像): ハッシュ付きファイル名(例 app.abc123.js)なら強キャッシュ
Cache-Control: public, max-age=31536000, immutable
注意点
- 「
no-cacheとno-storeは別物」no-store: そもそも保存しないno-cache: 保存して良いが使う前に確認する
- SPA/アセットは「ファイル名に指紋(hash)+長期キャッシュ」が最も堅い。