セキュリティヘッダーとは、Webサーバーがレスポンスに付けて「このページをどう扱うか」をブラウザに指示するHTTPヘッダーのことです。 HTTPSの強制(HSTS)、他サイトのiframeへの埋め込み制御(X-Frame-Options / frame-ancestors)、MIMEタイプの推測停止(X-Content-Type-Options)などを、サーバー設定の数行で有効にできます。

この記事では、主要なセキュリティヘッダー11種を「推奨/条件つき推奨/非推奨・廃止」に分けた一覧表と、Nginx・Apache・Next.js・Express(helmet)・Cloudflare・WordPress別のコピペ設定をまとめました。Nginx 1.24.0 と Express 5.2.1 + helmet 8.3.0 は実際に起動して curl -I で確認し、Nginxの add_header が location でまるごと消える落とし穴も実行結果つきで再現しています。CSPは別記事で詳しく扱っているため、本記事では概要と最小例に絞ります。

セキュリティヘッダーの早見表

推奨値は OWASP HTTP Headers Cheat Sheet と MDN の記載(2026年10月時点で確認)をもとにしています。

ヘッダー 区分 推奨値(まずはこれ) 何を防ぐ・何をする
Strict-Transport-Security(HSTS) 推奨 max-age=31536000; includeSubDomains 以後の接続をHTTPSに固定する
Content-Security-Policy(CSP) 推奨 最小なら frame-ancestors 'self'; object-src 'none'; base-uri 'self' 読み込めるスクリプト・埋め込み元を制限する
X-Content-Type-Options 推奨 nosniff MIMEタイプの推測(スニッフィング)を止める
X-Frame-Options 推奨(CSPのframe-ancestorsと併用) DENY または SAMEORIGIN iframe埋め込みによるクリックジャッキング対策
CSP frame-ancestors 推奨 frame-ancestors 'self' X-Frame-Optionsの後継。複数オリジンを指定できる
Referrer-Policy 推奨 strict-origin-when-cross-origin 外部サイトへ送るURL情報を減らす
Permissions-Policy 推奨 camera=(), microphone=(), geolocation=() 使わないブラウザ機能を無効にする
Cross-Origin-Opener-Policy(COOP) 推奨 same-origin 別オリジンのウィンドウとの参照を切り離す
Cross-Origin-Resource-Policy(CORP) 条件つき推奨 same-site(または same-origin) 自分のリソースを他サイトから読ませない
Cross-Origin-Embedder-Policy(COEP) 条件つき(必要なときだけ) require-corp または credentialless SharedArrayBuffer等が必要なときにCOOPと組で使う
X-XSS-Protection 非推奨 0(または送らない) 旧ブラウザのXSSフィルター。無効化が推奨
Server / X-Powered-By 除去推奨 送らない(バージョンを隠す) ソフトウェア名・バージョンの露出を減らす
Expect-CT / Public-Key-Pins 廃止 送らない どちらも使わない(OWASPが明記)
Feature-Policy 廃止(改名) Permissions-Policy に置き換える Permissions-Policyの旧名

迷ったら「HSTS・CSP(最小)・nosniff・X-Frame-Options・Referrer-Policy・Permissions-Policy・COOP」の7つを入れ、Server/X-Powered-Byを消す、が出発点です。COEP は外部画像や広告の表示に影響しやすいので、必要になったときに追加します。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「セキュリティヘッダー一覧|HSTS・CSPほか設定コード集」

各ヘッダーの意味と値の選び方

HSTS(Strict-Transport-Security)でHTTPSに固定する

HSTSは「このドメインには今後 max-age 秒のあいだHTTPSでしかアクセスしない」とブラウザに覚えさせるヘッダーです。 一度受け取ったブラウザは、http:// のリンクをクリックしても通信前に https:// へ内部で切り替えます。

Strict-Transport-Security: max-age=31536000; includeSubDomains
ディレクティブ 意味 注意点
max-age=秒 記憶する期間。31536000=1年 導入初期は 300(5分)など短くして様子を見ると戻しやすい
includeSubDomains サブドメインにも適用 HTTPのみのサブドメイン(社内用の検証環境など)があると開けなくなる
preload ブラウザ組み込みリストへの登録を希望する印 下の「preloadの注意」を読んでから付ける
  • HSTSはHTTPSのレスポンスでだけ有効です。 HTTPのレスポンスに付けてもブラウザは無視します(RFC 6797の仕様)。HTTP側は301でHTTPSへリダイレクトし、HTTPS側でHSTSを返します。
  • 段階的に伸ばすのがおすすめです。 300 → 86400 → 604800 → 31536000 と確かめながら伸ばします。

HSTS preloadの注意:登録すると簡単には外せない

preload を付けて hstspreload.org に申請すると、ドメインが Chrome などのブラウザに組み込みリストとして同梱されます。初回アクセスからHTTPSが強制される一方、次の点を押さえておきます。

項目 内容
申請条件(hstspreload.orgの記載) 有効な証明書、HTTP→HTTPSのリダイレクト、すべてのサブドメインがHTTPS、ベースドメインで max-age 31536000以上・includeSubDomains・preload を返す
削除 削除申請はできるが、各ブラウザのリリースに反映されて利用者の手元に届くまで数か月単位かかる
影響範囲 ドメイン配下のすべてのサブドメインがHTTPS必須になる

preloadは「全サブドメインをHTTPSで運用し続ける」と決めてから付けるのが安全です。普段の運用は preload なしのHSTSでも十分に効果があります。

CSP(Content-Security-Policy)は最小構成から

CSPは、ページが読み込んでよいスクリプト・画像・埋め込み元などを列挙するヘッダーです。 効果が大きい反面、サイトごとの調整が必要なので、詳しい書き方・段階導入(Report-Only)・nonceは別記事「CSP設定(Content-Security-Policy)|nginx段階導入」で解説しています。

ここでは、既存のスクリプトにほぼ影響せずに入れられる最小例だけ紹介します。

Content-Security-Policy: frame-ancestors 'self'; object-src 'none'; base-uri 'self'
ディレクティブ 効果
frame-ancestors 'self' 自サイト以外からのiframe埋め込みを禁止(X-Frame-Options SAMEORIGIN相当)
object-src 'none' <object> <embed> を無効化
base-uri 'self' <base> タグで相対URLの基準を書き換えられないようにする

X-Frame-Options と frame-ancestors はどちらを使う?

両方送るのが確実です。 MDNでは、より柔軟な指定ができる CSP の frame-ancestors が推奨され、両方ある場合は対応ブラウザで frame-ancestors が優先されます。X-Frame-Optionsは古いブラウザ向けの備えとして残します。

やりたいこと X-Frame-Options CSP frame-ancestors
どこからも埋め込ませない DENY frame-ancestors 'none'
自サイトからだけ許可 SAMEORIGIN frame-ancestors 'self'
特定の別オリジンも許可 指定できない(ALLOW-FROM は廃止) frame-ancestors 'self' https://partner.example.com

ポイント:frame-ancestors は <meta http-equiv> では効きません。 HTTPヘッダーで送ります。

X-Content-Type-Options

nosniff の1択です。ブラウザが Content-Type を無視して中身から種類を推測するのを止めます。JSやCSSを正しい Content-Type で配信していることが前提なので、設定後に表示崩れがあれば、サーバーのMIMEタイプ設定を確認します。

Referrer-Policy

主要ブラウザの既定値は strict-origin-when-cross-origin ですが、明示しておくと意図が設定ファイルに残ります。

値 同一オリジンへ 他オリジン(HTTPS)へ 向いている用途
strict-origin-when-cross-origin フルURL オリジンのみ 一般的なサイトの推奨値
same-origin フルURL 送らない 外部に一切出したくない管理画面
no-referrer 送らない 送らない 最も控えめ(アクセス解析の参照元も取れなくなる)

Permissions-Policy

カメラ・マイク・位置情報など、使わない機能を ()(空リスト)で無効にします。 旧名の Feature-Policy とは書式が違うので注意します。

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

自サイトだけ許可したい場合は geolocation=(self)、特定オリジンも許可するなら geolocation=(self "https://maps.example.com") と書きます。

COOP・CORP・COEP(Cross-Origin系3兄弟)

ヘッダー 推奨値 影響しやすいもの
COOP same-origin OAuthなどのポップアップログインで window.opener を使う場合は same-origin-allow-popups
CORP same-site 自社の別サブドメインから画像を読む構成なら same-site、外部に配る画像・CDNは cross-origin
COEP 必要なときだけ require-corp / credentialless 外部画像・埋め込み動画など、CORP/CORSのないリソースが読めなくなる

COEPは「SharedArrayBufferや高精度タイマーを使う(crossOriginIsolatedが必要)」ときに、COOPと組で入れるものです。通常のサイトでは無理に入れなくて大丈夫です。

X-XSS-Protection は「0」にする

かつてのブラウザ内蔵XSSフィルターを制御するヘッダーですが、現行の主要ブラウザではフィルター自体が削除されています。OWASPは0 を送るか、ヘッダーを送らないことを推奨しています。XSS対策はCSPと出力時のエスケープで行います。

Server・X-Powered-By を消す

Server: nginx/1.24.0 (Ubuntu) や X-Powered-By: Express は、使っているソフトとバージョンを外部に知らせます。脆弱性への対処そのものはアップデートで行い、その上で情報の露出を減らすのが目的です。

サーバー・フレームワーク別のコピペ設定

Nginx(1.24.0で動作確認)

ヘッダーは別ファイルにまとめて include すると、後述の継承の落とし穴を避けやすくなります。

# /etc/nginx/snippets/security_headers.conf
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Content-Security-Policy "frame-ancestors 'self'; object-src 'none'; base-uri 'self'" always;
# /etc/nginx/sites-available/example.conf
server_tokens off;   # Server: nginx(バージョンを出さない)

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;   # HTTPはHTTPSへ
}

server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/html;
    include /etc/nginx/snippets/security_headers.conf;

    location /static/ {
        include /etc/nginx/snippets/security_headers.conf;   # location で add_header を書くなら再掲
        add_header Cache-Control "public, max-age=86400" always;
    }
}
sudo nginx -t && sudo systemctl reload nginx

server_tokens の違いは次のとおりです(実行結果)。

server_tokens on;   → Server: nginx/1.24.0 (Ubuntu)
server_tokens off;  → Server: nginx

Server ヘッダー自体を消すには、headers-more モジュール(more_clear_headers Server;)や、商用版の設定が必要です。

Apache(mod_headers)

# a2enmod headers を有効にしたうえで、VirtualHost か .htaccess に記述
<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
    Header always set Cross-Origin-Opener-Policy "same-origin"
    Header always set Content-Security-Policy "frame-ancestors 'self'; object-src 'none'; base-uri 'self'"
    Header unset X-Powered-By
</IfModule>
# httpd.conf / apache2.conf(.htaccessでは書けない)
ServerTokens Prod
ServerSignature Off
  • Header always set の always を付けると、エラーレスポンス(404など)やリダイレクトにも付きます。
  • PHPの X-Powered-By は、php.ini の expose_php = Off でも消せます。
  • Apacheの設定はこの記事では実行していません。書式は Apache公式の mod_headers ドキュメントで確認しています。

Next.js(next.config)

App Router / Pages Router どちらでも、next.config の headers() で全パスに付けられます。

// next.config.ts
import type { NextConfig } from "next";

const securityHeaders = [
  { key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains" },
  { key: "X-Content-Type-Options", value: "nosniff" },
  { key: "X-Frame-Options", value: "SAMEORIGIN" },
  { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
  { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
  { key: "Cross-Origin-Opener-Policy", value: "same-origin" },
  { key: "Content-Security-Policy", value: "frame-ancestors 'self'; object-src 'none'; base-uri 'self'" },
];

const nextConfig: NextConfig = {
  poweredByHeader: false, // X-Powered-By: Next.js を消す
  async headers() {
    return [{ source: "/:path*", headers: securityHeaders }];
  },
};

export default nextConfig;
  • nonce付きのCSPを使う場合は、headers() ではなく Middleware(Proxy)でリクエストごとに生成します(Next.js公式のCSPガイド参照)。
  • output: "export"(静的書き出し)では headers() が効かないため、配信先(Nginx、Cloudflareなど)で設定します。
  • Next.jsの設定はこの記事では実行していません。書式は Next.js公式ドキュメント(next.config の headers)で確認してください。

Express(helmet 8.3.0で動作確認)

helmet を1行入れるだけで、主要なセキュリティヘッダーがまとめて付き、X-Powered-By も消えます。

npm i express helmet   # 確認時のバージョン:express 5.2.1 / helmet 8.3.0 / Node.js 22.22.2
// app.mjs
import express from "express";
import helmet from "helmet";

const app = express();
app.use(helmet());
app.get("/", (req, res) => res.send("ok"));
app.listen(7220, () => console.log("listening on 7220"));

helmetなしとありで curl -I した結果です(Date・ETag等は省略)。

$ curl -sI localhost:7222/   # helmet なし
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8

$ curl -sI localhost:7220/   # helmet() あり
HTTP/1.1 200 OK
Content-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
Origin-Agent-Cluster: ?1
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-DNS-Prefetch-Control: off
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 0
Content-Type: text/html; charset=utf-8

読み取れるポイント: - helmet 8 の既定値で X-XSS-Protection は 0、X-Powered-By は削除されています(OWASPの推奨と同じ)。 - Referrer-Policy の既定は no-referrer です。アクセス解析で参照元を使うなら下のように変更します。 - Permissions-Policy は helmet には含まれません。 必要なら自分でミドルウェアを足します。

値を調整した版です。

// app2.mjs
import express from "express";
import helmet from "helmet";

const app = express();
app.use(
  helmet({
    contentSecurityPolicy: {
      directives: {
        "default-src": ["'self'"],
        "img-src": ["'self'", "data:"],
        "frame-ancestors": ["'self'"],
      },
    },
    strictTransportSecurity: { maxAge: 31536000, includeSubDomains: true },
    referrerPolicy: { policy: "strict-origin-when-cross-origin" },
    xFrameOptions: { action: "sameorigin" },
  })
);
app.use((req, res, next) => {
  res.setHeader("Permissions-Policy", "camera=(), microphone=(), geolocation=()");
  next();
});
app.get("/", (req, res) => res.send("ok"));
app.listen(7221, () => console.log("listening on 7221"));

実行すると Referrer-Policy: strict-origin-when-cross-origin と Permissions-Policy: camera=(), microphone=(), geolocation=() が付くことを確認しました。

意外な点:directives で3つだけ指定しても、CSPには helmet の既定ディレクティブ(script-src など)が残ります。 これは useDefaults が既定で true のためです。指定したものだけにしたい場合は contentSecurityPolicy: { useDefaults: false, directives: {...} } とします。

Cloudflare

Cloudflareを前段に置いている場合は、オリジンを触らずにダッシュボードで付けられます。

やりたいこと 設定場所(2026年10月時点の公式ドキュメントの名称)
HSTSを有効にする SSL/TLS → Edge Certificates → HTTP Strict Transport Security (HSTS)
任意のヘッダーを付ける・消す Rules → Transform Rules → Response Header Transform Rules(Set static / Remove)
Pages・Workersの静的アセットに付ける プロジェクト直下の _headers ファイル
# _headers(Cloudflare Pages / Workers Static Assets)
/*
  X-Content-Type-Options: nosniff
  X-Frame-Options: SAMEORIGIN
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=()
  Cross-Origin-Opener-Policy: same-origin

オリジン(Nginxなど)とCloudflareの両方で同じヘッダーを付けると重複することがあるので、どちらで付けるかを1か所に決めます。Cloudflareの画面名は変わることがあるため、公式ドキュメントで確認してください(この記事では未操作)。

WordPress(functions.php)

テーマの functions.php(子テーマ推奨)に追加します。

<?php
// functions.php
add_action('send_headers', function () {
    if (is_admin()) {
        return; // 管理画面は除外(必要に応じて)
    }
    header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
    header('X-Content-Type-Options: nosniff');
    header('X-Frame-Options: SAMEORIGIN');
    header('Referrer-Policy: strict-origin-when-cross-origin');
    header('Permissions-Policy: camera=(), microphone=(), geolocation=()');
    header_remove('X-Powered-By');
});
  • send_headers はフロント側のページで呼ばれるフックです。画像・CSSなどの静的ファイルや wp-admin にはNginx/Apache側で付けるほうが確実です。
  • サーバー設定とfunctions.phpの両方で付けると、同じヘッダーが2つ返ることがあります。どちらか一方にそろえます。
  • WordPress上での動作はこの記事では未実行です(PHPの header() / header_remove() は標準関数)。

Nginxのadd_header継承の落とし穴を再現する

Nginxの add_header は「その階層に add_header が1つもないときだけ」上の階層から継承されます。 location に Cache-Control を1つ足しただけで、server に書いたセキュリティヘッダーがすべて消えます。

直す前:location で add_header を書く

server {
    listen 7223;
    root /tmp/t122html;
    add_header X-Content-Type-Options "nosniff";
    add_header X-Frame-Options "SAMEORIGIN";

    location /static/ {
        add_header Cache-Control "public, max-age=86400";
    }
}

実行結果(nginx 1.24.0、Date等は省略)です。

$ curl -sI localhost:7223/
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN

$ curl -sI localhost:7223/static/a.css
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/css
Cache-Control: public, max-age=86400        ← nosniff と X-Frame-Options が消えた

$ curl -sI localhost:7223/nothing
HTTP/1.1 404 Not Found
Server: nginx
Content-Type: text/html                       ← always がないので404には付かない

消える理由は2つです。

現象 原因 直し方
/static/ でヘッダーが消える location に add_header があるため、server の add_header が継承されない location にも include で再掲する(1.29.3以降は add_header_inherit merge; も可)
404・500で付かない always なしの add_header は 200, 201, 204, 206, 301, 302, 303, 304, 307, 308 にだけ付く always を付ける

直した後:include で再掲し always を付ける

前述の security_headers.conf を server と location の両方で include した結果です。

$ curl -skI https://localhost:7224/static/a.css | grep -cE "Strict|X-Content|X-Frame|Referrer|Permissions|Cross-Origin-Opener|Content-Security"
7
$ curl -skI https://localhost:7224/static/a.css | grep Cache-Control
Cache-Control: public, max-age=86400
$ curl -skI https://localhost:7224/nothing | head -1
HTTP/1.1 404 Not Found        ← 404 にも同じ7つのヘッダーが付いた

Nginx 1.29.3 以降なら add_header_inherit merge; で上位の値を引き継げます(nginx公式ドキュメントで確認。1.24.0では使えないため未実行)。

# nginx 1.29.3+
location /static/ {
    add_header_inherit merge;
    add_header Cache-Control "public, max-age=86400" always;
}

設定を確認するコマンドとツール

方法 コマンド・場所 確認できること
curl curl -sI https://example.com/ レスポンスヘッダー全体
curl(絞り込み) curl -sI https://example.com/ | grep -iE "strict|content-security|x-frame" 特定ヘッダーの有無
curl(エラー時) curl -sI https://example.com/not-found-page 404にも付いているか(always の確認)
curl(静的ファイル) curl -sI https://example.com/static/app.css locationごとに消えていないか
ブラウザ DevTools → Network → 対象リクエスト → Headers 実際にブラウザが受け取った値
HTTP Observatory MDN上の HTTP Observatory(developer.mozilla.org/observatory) 公開サイトの総合評価と改善点
設定の静的チェック gixy(Nginx設定の解析ツール) add_header の再定義などを検出

URLを並べて一括チェックできるNode.jsスクリプトです(Node.js 18以降の組み込み fetch を使用)。

// check-headers.mjs  使い方: node check-headers.mjs https://example.com/
const url = process.argv[2];
const want = [
  "strict-transport-security",
  "content-security-policy",
  "x-content-type-options",
  "x-frame-options",
  "referrer-policy",
  "permissions-policy",
  "cross-origin-opener-policy",
];
const unwanted = ["x-powered-by", "server"];
const res = await fetch(url, { redirect: "manual" });
console.log(`${res.status} ${url}`);
for (const h of want) console.log(res.headers.has(h) ? "OK  " : "なし", h, res.headers.get(h) ?? "");
for (const h of unwanted) if (res.headers.has(h)) console.log("確認", h, res.headers.get(h));

上の「直す前」の Nginx の /static/a.css に実行すると、7項目すべてが「なし」、確認 server nginx と表示されました(直した後の 7224 番では7項目すべて「OK」)。

トップページだけでなく、静的ファイル・404ページ・APIのパスも1つずつ確認すると、継承の漏れに気づけます。

導入時のよくあるつまずきと対処

症状 原因 対処
一部のパスだけヘッダーがない Nginxのadd_header継承 location に include で再掲、always を付ける
同じヘッダーが2つ返る Nginx・アプリ・CDNの複数箇所で付与 付ける場所を1か所に決める(アプリ側で消すなら proxy_hide_header)
外部サービスのiframe埋め込みが表示されない 埋め込まれる側(自サイト)の X-Frame-Options / frame-ancestors 許可したいオリジンを frame-ancestors に追加
ポップアップログイン後に画面が戻らない COOP same-origin で opener が切れた same-origin-allow-popups にする
HTTPのサブドメインが開けない HSTS includeSubDomains サブドメインをHTTPS化するか、includeSubDomains を外して max-age 切れを待つ

よくある質問

Q. セキュリティヘッダーはどれから入れればよいですか? A. 影響が小さく効果が大きい順に、X-Content-Type-Options、Referrer-Policy、X-Frame-Options(+frame-ancestors)、Permissions-Policy、HSTS(短いmax-ageから) がおすすめです。CSPは Report-Only で様子を見てから本番の値にします。

Q. X-Frame-Options は廃止されたのですか? A. 廃止ではありません。より柔軟な CSP の frame-ancestors が推奨されていますが、古いブラウザ向けに X-Frame-Options も併記するのが一般的です。両方ある場合、対応ブラウザでは frame-ancestors が使われます。

Q. HSTSを入れたあとHTTPに戻したくなったら? A. max-age=0 を HTTPS で返すと、次回アクセス時にブラウザの記憶が消えます。 ただし一度もアクセスしない利用者のブラウザには max-age の期間残ります。preload登録済みの場合は、リストからの削除が各ブラウザに届くまで数か月かかります。

Q. helmet を使えば Express は十分ですか? A. 主要なヘッダーはそろいますが、Permissions-Policy は含まれず、CSP の既定値はサイトに合わせた調整が必要です。Referrer-Policy の既定 no-referrer も用途に合わせて見直します。

まとめ

  • 基本の7つ(HSTS・最小CSP・nosniff・X-Frame-Options・Referrer-Policy・Permissions-Policy・COOP)を入れ、Server/X-Powered-Byを減らすのが出発点です。
  • X-XSS-Protection は 0、Expect-CT と Public-Key-Pins は送らないのが現在の推奨です。
  • HSTSは短い max-age から伸ばし、preload は全サブドメインのHTTPS運用を決めてから付けます。
  • Nginxは location に add_header を書くと上位の設定が消えるので、include で再掲し always を付けます(1.29.3以降は add_header_inherit merge)。
  • Express は helmet 1行で多くがそろう一方、Permissions-Policy の追加と既定値の見直しが必要です。
  • 確認は curl -I をトップ・静的ファイル・404で行うと、継承漏れに気づけます。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「セキュリティヘッダー一覧|HSTS・CSPほか設定コード集」

株式会社RJCでは、Webサイトを安全に届けるための設定を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?