どのサンプルも同じ初期値を設定します。ホスティング基盤がすでにStrict-Transport-Securityを送っている場合があるため、Vercel、Netlify、Next.jsのサンプルには含めていません。実際のレスポンスを確認し、ない場合にのみ追加してください。
nginx
HTTPSを提供するserverブロックに行を追加します。alwaysパラメーターを付けると、エラーレスポンスにも追加されます。独自のadd_header行を持つlocationブロックでは、serverブロックから継承されるadd_headerがすべて失われるため、そこにも同じ一式を書くか、1つのincludeファイルにまとめてください。
# In the server block that serves HTTPS (listen 443 ssl)
add_header Strict-Transport-Security "max-age=300" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Apache
mod_headersを有効にし、ポート443のバーチャルホスト、またはAllowOverride FileInfoが設定された場所の.htaccessに行を追加します。Header always setはエラーレスポンスとリダイレクトにも適用されます。
# <VirtualHost *:443> or .htaccess; needs mod_headers (Debian/Ubuntu: a2enmod headers)
Header always set Strict-Transport-Security "max-age=300"
Header always set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Cloudflare
ダッシュボードでホスト名に対するResponse Header Transform Ruleを作成し、各ヘッダーをSet static操作で追加します。この操作はオリジンから届いた同名のヘッダーを置き換えます。HSTSにはSSL/TLSのEdge Certificatesに専用の設定があるため、その設定とルールのどちらか一方だけを使ってください。メニュー名はダッシュボードのバージョンによって異なる場合があります。
Rule type Response Header Transform Rule
When Hostname equals example.com
Then Set static, one row per header:
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
X-Frame-Options SAMEORIGIN
Permissions-Policy camera=(), microphone=(), geolocation=()
Content-Security-Policy-Report-Only default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'
HSTS SSL/TLS > Edge Certificates > HTTP Strict Transport Security (HSTS)
Vercel
プロジェクトのルートにあるvercel.jsonにheadersの項目を追加します。sourceパターン/(.*)はすべてのパスに一致します。一部のルートに別のポリシーが必要なら範囲を絞ってください。
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Content-Security-Policy-Report-Only", "value": "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" },
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
Netlify
公開ディレクトリ、つまりNetlifyがデプロイするフォルダーに_headersという名前のファイルを作成します。/*のようなパスの行の後に、インデントした「名前: 値」の行を続けます。同じルールはnetlify.tomlの[[headers]]にも書けます。
/*
Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Next.js
next.config.jsのasync headers()関数からヘッダーを返します。source '/:path*'ですべてのルートが対象になります。静的エクスポート(output: 'export')ではheaders()が実行されないため、その場合はエクスポートしたファイルを配信するホスト側でヘッダーを設定してください。
// next.config.js
const securityHeaders = [
{ key: 'Content-Security-Policy-Report-Only', value: "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" },
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
];
module.exports = {
async headers() {
return [{ source: '/:path*', headers: securityHeaders }];
},
};
デプロイ後にチェッカーを再実行してください。最終レスポンスを読むため、CDNやプラットフォームが実際に送っている内容がわかります。続けて、ブラウザの開発者ツールでエラーページと静的ファイルを開いてください。ヘッダーが一部のレスポンスにしか設定されていないことはよくあります。