Security-Header-Architektur für Netlify

Alle Security Headers zentral konfigurieren: netlify.toml für statische Header, _headers als Alternative und Edge Functions für dynamische Nonces.

Netlify · Schritt für Schritt

Header-Architektur auf Netlify

Netlify bietet drei Konfigurationswege für HTTP-Response-Header. Die richtige Wahl hängt von Ihrem Anwendungsfall ab: netlify.toml für versionierte, zentrale Konfigurationen, _headers für einfache Plaintext-Regeln, und Edge Functions (Deno-Runtime) für dynamische Header wie CSP-Nonces.

Die Prioritätsreihenfolge ist entscheidend: Edge Functions überschreiben netlify.toml, und netlify.toml überschreibt _headers. Dieses Kapitel zeigt die empfohlene Architektur und erklärt, wann welcher Konfigurationsweg sinnvoll ist. Der Wolf-Agents Web Security Check bewertet Ihre Header-Konfiguration mit 166 Prüfpunkten.

1 Schritt 1 von 3

Statische Header per netlify.toml

Die netlify.toml ist der empfohlene Weg für alle statischen Security Headers. Sie liegt im Repo-Root, ist versioniert und wird bei jedem Deploy automatisch angewendet. Die Konfiguration gilt für alle Deployments inklusive Deploy Previews und Branch Deploys.

netlify.toml Empfohlen
# netlify.toml — Alle Security Headers zentral
[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-Content-Type-Options = "nosniff"
    Referrer-Policy = "strict-origin-when-cross-origin"
    Permissions-Policy = "camera=(), microphone=(), geolocation=(), payment=()"
    Strict-Transport-Security = "max-age=31536000; includeSubDomains; preload"
    Content-Security-Policy = "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'"
    Cross-Origin-Opener-Policy = "same-origin"
    Cross-Origin-Resource-Policy = "same-origin"
Wildcard-Pattern /*

Das Pattern /* matcht alle Pfade. Sie können spezifischere Patterns verwenden — z.B. /api/* für API-Routen oder /assets/* für statische Assets mit abweichenden Cache-Headern.

2 Schritt 2 von 3

_headers als Alternative

Die _headers-Datei verwendet eine einfache Plaintext-Syntax und liegt im Publish-Verzeichnis (Build-Output). Sie eignet sich für Projekte ohne netlify.toml oder als Ergänzung für pfadspezifische Header-Regeln.

_headers (im Publish-Verzeichnis) Alternative
# _headers — Alternative im Publish-Verzeichnis
/*
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'; base-uri 'self'; form-action 'self'
Die _headers-Datei muss im Publish-Verzeichnis landen, nicht im Repo-Root. Bei Frameworks wie Next.js, Gatsby oder Astro müssen Sie die Datei in den public/-Ordner legen, damit sie im Build-Output erscheint. Wenn netlify.toml denselben Header definiert, gewinnt netlify.toml.
3 Schritt 3 von 3

Edge Functions für dynamische Header

Netlify Edge Functions laufen in einer Deno-Runtime am Edge und können pro Request dynamische Header generieren. Das ist ideal für CSP-Nonces, die bei jedem Request einzigartig sein müssen. Edge Functions überschreiben sowohl netlify.toml als auch _headers.

netlify/edge-functions/security-headers.ts Dynamisch
// netlify/edge-functions/security-headers.ts
import type { Context } from "https://edge.netlify.com";

export default async (request: Request, context: Context) => {
  const response = await context.next();

  // Statische Header
  response.headers.set("X-Frame-Options", "DENY");
  response.headers.set("X-Content-Type-Options", "nosniff");
  response.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
  response.headers.set("Permissions-Policy", "camera=(), microphone=(), geolocation=()");
  response.headers.set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");

  // Dynamischer CSP mit Nonce
  const nonce = crypto.randomUUID().replace(/-/g, "");
  response.headers.set("Content-Security-Policy",
    `default-src 'self'; script-src 'self' 'nonce-${nonce}'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'`
  );

  return response;
};

export const config = { path: "/*" };
Deno, nicht Node.js

Netlify Edge Functions nutzen Deno, nicht Node.js. Imports verwenden URL-basierte Module (https://edge.netlify.com). Node.js-Pakete wie helmet funktionieren hier nicht. Für serverseitigen Code nutzen Sie stattdessen Netlify Functions (Node.js).

Häufige Fehler

_headers nicht im Build-Output

Die _headers-Datei liegt im Repo-Root statt im Publish-Verzeichnis. Bei Frameworks legen Sie die Datei in public/ oder static/.

netlify.toml überschreibt _headers

Wenn beide denselben Header definieren, gewinnt netlify.toml. Verwenden Sie konsistent nur einen Weg oder teilen Sie Header gezielt auf.

Edge Function path fehlt

Ohne export const config = { path: "/*" } wird die Edge Function nicht ausgeführt. Alternativ konfigurieren Sie den Pfad in der netlify.toml unter [edge_functions].

Deploy Preview mit anderen Headern

Deploy Previews unter deploy-preview-*.netlify.app erhalten dieselben Header. Testen Sie Header-Änderungen in Deploy Previews, bevor Sie in Produktion deployen.

Compliance-Relevanz

Eine konsolidierte Header-Architektur ist die Grundlage für nachweisbare Sicherheit. NIS2 fordert technische Maßnahmen zur Cybersicherheit, und PCI DSS 4.0 verlangt die Kontrolle aller geladenen Scripts. Mit einer zentralen Konfiguration in netlify.toml oder Edge Functions können Sie jede Änderung per Git nachvollziehen. Der Wolf-Agents Web Security Check dokumentiert den aktuellen Stand mit 166 Prüfpunkten.

Wie steht Ihre Domain bei Implementierungs-Architektur?

Prüfen Sie es jetzt — kostenlos, ohne Registrierung, mit 166 Prüfpunkte.