Skip to content

Instantly share code, notes, and snippets.

@nurmdrafi
Last active April 22, 2024 11:19
Show Gist options
  • Save nurmdrafi/f427f3e1ae968aa008ced80926009486 to your computer and use it in GitHub Desktop.
Save nurmdrafi/f427f3e1ae968aa008ced80926009486 to your computer and use it in GitHub Desktop.
NextJS Content Security Policy

Related Docs

Step 1: Add Content Security Policy Header using Nonce

Add the following to your app/layout.tsx or pages/_app.tsx or pages/_document.tsx

import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    
    // Nonce is a unique, random string of characters created for a one-time use. 
    // It can help you to avoid using the CSP unsafe-inline directive, which would allowlist all inline scripts or styles.
    const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
    
    // Content Security Policy Header
    const cspHeader = `
      script-src 'self' 'unsafe-eval' 'unsafe-inline' 'nonce-${ nonce }';
      style-src 'self' 'unsafe-inline';
      img-src 'self' blob: data:;
      font-src 'self';
      object-src 'none';
      base-uri 'self';
      form-action 'self';
      frame-src 'self';
      worker-src 'self' blob:;
    ` 
    return (
      <Html>
        <Head nonce={ nonce }>
          <meta httpEquiv="Content-Security-Policy" content={ cspHeader.replace(/\s{2,}/g, ' ').trim() } />
        </Head>
        <body>
          <Main />
          <NextScript nonce={ nonce } />
        </body>
      </Html>
    )
  }
}

export default MyDocument

Step 2: Add Additional Header For Content Security

Update next.config.js

// Configuration options for Next.js
const nextConfig = {
  output: "standalone",
  reactStrictMode: false,
  swcMinify: true,
  eslint: {
    dirs: ["."],
  },

  // Additional Headers For Content Security
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [
          {
            key: 'Referrer-Policy',
            value: 'no-referrer, strict-origin-when-cross-origin'
          },
          {
            key: 'Strict-Transport-Security',
            value: 'max-age=31536000'
          },
          {
            key: 'X-DNS-Prefetch-Control',
            value: 'on'
          },
          {
            key: 'X-Frame-Options',
            value: 'DENY'
          },
          {
            key: 'X-Content-Type-Options',
            value: 'nosniff'
          },
          {
            key: 'X-XSS-Protection',
            value: '1; mode=block'
          },
        ],
      },
    ];
  },
};

module.exports = nextConfig;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment