Oteto Blogのロゴ

【Next.js】HTTPレスポンスヘッダ(Security Headers)を設定する

やりたいこと

Security HeadersのスコアがDだった

Security Headerの対応具合を教えてくれるSecurity Headersで自分のサイトを分析したところ、Dというよろしくないスコアが出てしまった。

このままではセキュリティ的によろしくないので適切なHTTPレスポンスヘッダを設定していく。

  • Next.js製
  • デプロイ先はVercel
  • HTTPレスポンスヘッダ周りは何も手を施していない

ちなみに自分のサイトは上記のような状態で、実を言うとデフォルトでもNext.jsもしくはVercelがよしなに設定してくれていると思っていた。

解決法

/** @type {import('next').NextConfig} */
const nextConfig = {
  async headers() {
    return [
      {
        source: "/(.*)", // 全てのパス
        headers: [
          {
            key: "<SOME_KEY>",
            value: "<SOME_VALUE>",
          },
        ],
      },
    ];
  },
};

module.exports = nextConfig;

next.config.jsにて、適用したいパスと任意のHTTPヘッダーのkeyvalueを指定する。指定可能なものは公式ドキュメントから確認できる。

/** @type {import('next').NextConfig} */
const nextConfig = {
  async headers() {
    return [
      {
        source: "/(.*)", // 全てのパス
        headers: [
          {
            key: "X-DNS-Prefetch-Control",
            value: "on",
          },
          {
            key: "X-Content-Type-Options",
            value: "nosniff",
          },
          {
            key: "X-Frame-Options",
            value: "sameorigin",
          },
          {
            key: "X-XSS-Protection",
            value: "1; mode=block",
          },
          {
            key: "Referrer-Policy",
            value: "strict-origin-when-cross-origin",
          },
          {
            key: "Permissions-Policy",
            value: "camera=(), microphone=()",
          },
          {
            key: "Content-Security-Policy",
            value: "script-src 'self' 'unsafe-inline' www.googletagmanager.com",
          },
        ],
      },
    ];
  },
};

module.exports = nextConfig;

今回はひとまずSecurity Headersの基準に沿って上記のように指定した。

CSPではインラインのものとGoogle Analyticsによる計測のためのスクリプトは許可している。

Security HeadersのスコアがAに上昇した

するとスコアがAになったのでひとまず最低限の対応はできた。

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "<SOME_KEY>",
          "value": "<SOME_VALUE>"
        }
      ]
    }
  ]
}

ちなみにSSG(static export)している場合はnext.config.jsでのheaders指定が無効になるが、Vercelにデプロイしている場合に限りvercel.jsonに設定を追記することで代替できる。