Naar de inhoud
websitecontrole.nl
Advies

Beveiliging afstemmen op Next.js

Op Next.js zet je de headers in je eigen config of middleware, niet in een CMS. Hieronder per bevinding waar de fix woont, met code die je kunt overnemen.

Response-headers (HSTS, clickjacking, MIME-sniffing, referrer, permissions)

Deze zet je in next.config.js via de headers()-functie, die op elk pad geldt. Let op: een statische export (output: "export") serveert geen headers vanuit Next, dan horen ze op de host (bijvoorbeeld een _headers-bestand op Netlify of Cloudflare Pages, of vercel.json).

next.config.js
const securityHeaders = [
  { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains; preload' },
  { key: 'X-Frame-Options', value: 'SAMEORIGIN' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
  { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
];

module.exports = {
  async headers() {
    return [{ source: '/:path*', headers: securityHeaders }];
  },
};

De Content-Security-Policy (met een nonce)

Een strikte CSP zet je in Next het beste met een nonce per request via middleware, zodat je inline scripts kunt toestaan zonder unsafe-inline. De nonce geef je door aan je scripts.

  1. Zet de policy eerst in report-only (de Content-Security-Policy-Report-Only-header), dan breekt hij niets maar meldt hij wel wat hij zou blokkeren.
  2. Verzamel de meldingen met een tool als Sentry, Report URI of URIports, of lees ze in je browserconsole.
  3. Sta toe wat legitiem geblokkeerd wordt, tot er geen echte meldingen meer binnenkomen.
  4. Hernoem de header naar Content-Security-Policy om de policy af te dwingen.
middleware.js
import { NextResponse } from 'next/server';

export function middleware() {
  const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
  const csp = [
    "default-src 'self'",
    `script-src 'self' 'nonce-${nonce}' 'strict-dynamic'`,
    "object-src 'none'",
    "base-uri 'self'",
  ].join('; ');

  const response = NextResponse.next();
  response.headers.set('Content-Security-Policy-Report-Only', csp);
  response.headers.set('x-nonce', nonce);
  return response;
}

De verbinding (HTTPS en het certificaat)

HTTPS afdwingen en het certificaat regelt je host of CDN. Zorg dat http naar https doorstuurt en dat het certificaat geldig is en niet verlopen. De meeste hosts en CDN's doen dit met een schakelaar of een gratis Let's Encrypt-certificaat.

Lees verder

DNS-records (SPF, DMARC, DNSSEC, IPv6)

Deze staan los van je site: het zijn records bij je domein. Je zet ze bij je DNS-provider of domeinregistrar, niet in je CMS of op je host. SPF en DMARC gaan over wie mail namens je domein mag sturen, DNSSEC ondertekent je DNS, en IPv6 is de enige waar de host eerst een AAAA-record en verbinding moet aanbieden voordat je die kunt zetten.

Verdieping

Advies voor een ander platform