Next.jsアプリにContent-Security-Policyを設定する

公開日時

Next.jsアプリのセキュリティ対策の一環としてContent-Security-Policyの設定を行った。

下記記事を参考にさせていただき、Strict CSPを設定。

// pages/_document.tsx
import { randomBytes } from 'crypto'
import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document'
import React from 'react'

type WithNonceProp = {
  nonce: string
}
export default class MyDocument extends Document<WithNonceProp> {
  static async getInitialProps(ctx: DocumentContext) {
    const initialProps = await Document.getInitialProps(ctx)
    const nonce = randomBytes(128).toString('base64')
    return {
      ...initialProps,
      nonce,
    }
  }
  render() {
    const nonce = this.props.nonce
    const csp = `object-src 'none'; base-uri 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: http: 'nonce-${nonce}' 'strict-dynamic'`

    return (
      <Html>
        <Head nonce={nonce}>
          <meta httpEquiv="Content-Security-Policy" content={csp} />
        </Head>
        <body>
          <Main />
          <NextScript nonce={nonce} />
        </body>
      </Html>
    )
  }
}

nonceはリクエストごとに更新すべきたが、ISR(Incremental Static Regeneration)のアプリなので次回の更新までは同じnonceになってしまう。

SSRにする予定は今のところないのと、何も対策しないよりは良いだろうということでnonceがしばらくキャッシュされてしまうのは許容することにした。

参考


Related #next.js

FigmaでSVG Octocatを作る その3

アウトライン化大事

Next.jsプロジェクトのGoogle Analytics V3をV4に更新する

トラッキングIDの差し替えのみで対応が完了した

Vercelで指定のブランチのみデプロイを実行する

Ignored Build Stepを設定した