Closed10

[Next.js] セキュリティ向上のために Security Headers を設定する

ピン留めされたアイテム
へぶんへぶん

TL;DR

  • Vercel にデプロイしない場合、デフォルトだと Strict-Transport-Security が追加されない (HTTPS を強制するやつ)
  • next.config.js で HTTP response header を一括で設定できる
  • 対応度合いの確認には Security Headers が便利
へぶんへぶん

作業内容

  • ルート以下に headers.js を追加
  • next.config.jsheaders()の初期化を追加
へぶんへぶん
headers.js
module.exports = [
    {
        key: 'X-DNS-Prefetch-Control',
        value: 'on',
    },
    {
        key: 'Strict-Transport-Security',
        value: 'max-age=63072000; includeSubDomains; preload',
    },
    // todo: Server が決まってる場合は設定できる
    // {
    //     key: 'Server',
    //     value: 'Apache', // phony server value
    // },
    {
        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: 'same-origin',
    },
    {
        key: 'Permissions-Policy',
        value: 'camera=*',
    },
    // todo: Content Security Policy を適用する
    {
        key: 'Content-Security-Policy',
        value: 'default-src \'self\'', 
    },
];

以下は next.config.js の例。

next.config.js
// 追加した `headers.js` を読み込む
const headers = require('./headers');

module.exports = _ => {
  return {
    reactStrictMode: true,
    eslint: {
      dirs: ['src']
    },
    async headers() {
      return [
        {
         // 全てのパスに Security Headers を適用する
          source: '/(.*)',
          headers,
        },
      ];
    },
  }
}
ueshouesho
    async headers() {
      return [
        {
         // 全てのパスに Security Headers を適用する
          source: '/(.*)',
          headers,
        },
      ];
    },

このままですとルートパスで追加した設定が反映されないです。
全てのパスに適用するには、 source: '/:path*' にする必要があります。

自分もハマったのでここに残しておきます。

参考

https://nextjs.org/docs/pages/api-reference/next-config-js/headers#headers-with-i18n-support

      {
        // this gets converted to /(en|fr|de)/(.*) so will not match the top-level
        // `/` or `/fr` routes like /:path* would
        source: '/(.*)',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
このスクラップは2021/10/08にクローズされました