Reporting API für Nuxt 3 konfigurieren

Schritt-für-Schritt-Anleitung: Reporting-Endpoints in Nuxt 3 konfigurieren und CSP-Violation-Reports per Nitro API Route empfangen.

Nuxt 3 · Schritt für Schritt

Reporting API in Nuxt 3

Die Reporting API ermöglicht es Browsern, strukturierte Berichte über CSP-Violations, Deprecations, Netzwerkfehler und Crashes an einen Server-Endpoint zu senden. Mit 4 von 166 Punkten ist die Reporting API ein Faktor im Wolf-Agents Web Security Check und ein unverzichtbares Werkzeug für dauerhaftes Security-Monitoring Ihrer Webanwendung.

In Nuxt 3 konfigurieren Sie den Reporting-Endpoints-Header per nuxt-security Modul, routeRules oder Nitro Server Middleware. Der Report-Empfänger wird als Nitro API Route implementiert, die Reports entgegennimmt, validiert und speichert. Ein häufiger Irrtum: useHead() setzt HTML-Meta-Tags, keine HTTP-Response-Header. Reporting-Endpoints müssen als HTTP-Header gesendet werden.

1 Schritt 1 von 3

Reporting-Endpoints konfigurieren

Setzen Sie den Reporting-Endpoints-Header, der dem Browser mitteilt, wohin Reports gesendet werden sollen. Definieren Sie separate Endpoints für CSP-Violations und allgemeine Reports. Das nuxt-security Modul kombiniert Reporting mit CSP-Konfiguration in einer Datei.

nuxt.config.ts nuxt-security
// nuxt.config.ts — Reporting mit nuxt-security
export default defineNuxtConfig({
  modules: ['nuxt-security'],

  security: {
    headers: {
      contentSecurityPolicy: {
        'default-src': ["'self'"],
        'script-src': ["'self'", "'nonce-{{nonce}}'"],
        'report-uri': ['/api/reports/csp'],
      },
    },
  },

  routeRules: {
    '/**': {
      headers: {
        'Reporting-Endpoints':
          'csp-endpoint="/api/reports/csp", default="/api/reports/default"',
      },
    },
  },
})

Ohne nuxt-security setzen Sie den Header per routeRules. Diese Methode ist deklarativ und benötigt kein zusätzliches Modul. Sie können report-to und das ältere report-uri parallel setzen, um maximale Browser-Kompatibilität zu erreichen.

nuxt.config.ts routeRules
// nuxt.config.ts — Reporting per routeRules (ohne nuxt-security)
export default defineNuxtConfig({
  routeRules: {
    '/**': {
      headers: {
        'Reporting-Endpoints':
          'csp-endpoint="/api/reports/csp", default="/api/reports/default"',
        'Content-Security-Policy':
          "default-src 'self'; script-src 'self'; report-uri /api/reports/csp; report-to csp-endpoint",
      },
    },
  },
})
server/middleware/reporting.ts Middleware
// server/middleware/reporting.ts — Nitro Middleware
export default defineEventHandler((event) => {
  setHeader(event,
    'Reporting-Endpoints',
    'csp-endpoint="/api/reports/csp", default="/api/reports/default"'
  );
})
SSR vs. SSG

Reporting-Endpoints funktionieren nur im SSR-Modus, da HTTP-Header bei jedem Request gesetzt werden müssen. Bei nuxt generate (SSG) gibt es keinen Node-Server. Konfigurieren Sie Reporting-Header dann auf Ihrem Hosting-Provider (Vercel, Netlify) oder Reverse Proxy (Nginx).

2 Schritt 2 von 3

Report-Empfänger implementieren

Erstellen Sie Nitro API Routes, die Reports empfangen. Browser senden Reports als POST-Requests mit JSON-Body. Der CSP-Endpoint empfängt Violation-Reports, der Default-Endpoint alle anderen Report-Typen (Deprecations, Crashes, Interventions). Antworten Sie immer mit Status 204 (No Content).

server/api/reports/csp.post.ts CSP-Endpoint
// server/api/reports/csp.post.ts — Report-Empfänger
export default defineEventHandler(async (event) => {
  const body = await readBody(event);
  const ip = getRequestHeader(event, 'x-forwarded-for');

  // Reports filtern und loggen
  const reports = Array.isArray(body) ? body : [body];
  for (const report of reports) {
    const b = report.body || report;
    console.log('[CSP Report]', {
      blockedUri: b['blocked-uri'],
      violatedDirective: b['violated-directive'],
      documentUri: b['document-uri'],
      ip,
    });
  }

  // 204 No Content — Browser erwartet keinen Body
  setResponseStatus(event, 204);
  return null;
})
server/api/reports/default.post.ts Default-Endpoint
// server/api/reports/default.post.ts — Allgemeiner Report-Empfänger
export default defineEventHandler(async (event) => {
  const body = await readBody(event);

  // Deprecations, Interventions, Crashes loggen
  console.log('[Report]', JSON.stringify(body));

  setResponseStatus(event, 204);
  return null;
})
Report-Volume beachten

Hochfrequentierte Seiten können tausende Reports pro Stunde generieren. Implementieren Sie Rate-Limiting und Sampling in Ihrem Report-Endpoint, um Überlastung zu vermeiden. Browser batchen Reports und senden sie verzögert, nicht synchron beim Violation-Zeitpunkt.

3 Schritt 3 von 3

Reporting verifizieren

Erstellen Sie einen Production-Build und prüfen Sie den Reporting-Endpoints-Header. Der Dev-Server kann andere Header setzen als der Produktiv-Build. Testen Sie immer mit nuxi build, nicht mit nuxi dev.

Terminal Verifizieren
# Production-Build erstellen und starten
npx nuxi build
node .output/server/index.mjs

# Reporting-Endpoints Header prüfen
curl -sI https://ihre-domain.de | grep -i reporting

# Erwartete Ausgabe:
# Reporting-Endpoints: csp-endpoint="/api/reports/csp", default="/api/reports/default"

# Report-Endpoint testen (simulierter CSP-Report)
curl -X POST https://ihre-domain.de/api/reports/csp \
  -H "Content-Type: application/json" \
  -d '{"blocked-uri":"https://evil.com","violated-directive":"script-src"}'

# Erwartete Antwort: HTTP 204 No Content
Leeren Sie nach dem Verifizieren den Cache: npx nuxi cleanup && npx nuxi dev. Im Dev-Modus können gecachte Builds alte Header-Konfigurationen beibehalten.

Häufige Fehler

report-uri vs. Reporting-Endpoints verwechselt

report-uri ist die ältere CSP-Level-2-Direktive. report-to mit Reporting-Endpoints ist der moderne Standard (CSP Level 3). Setzen Sie beide parallel für maximale Browser-Kompatibilität: ältere Browser nutzen report-uri, Chrome und Edge nutzen report-to.

useHead() setzt keine HTTP-Header

useHead() in Nuxt 3 setzt HTML-Meta-Tags im <head>, keine HTTP-Response-Header. Reporting-Endpoints müssen per routeRules, nuxt-security oder Nitro Middleware als HTTP-Header konfiguriert werden.

CORS blockiert Report-Endpoint

Browser senden Reports als Cross-Origin POST an den konfigurierten Endpoint. Verwenden Sie relative Pfade (/api/reports/csp) statt absoluter URLs, damit Reports auf derselben Domain ankommen und kein CORS-Konflikt entsteht.

nuxt-security überschreibt routeRules-Reporting

Wenn nuxt-security aktiv ist, hat es Vorrang über manuelle routeRules für CSP-Header. Konfigurieren Sie report-uri und report-to innerhalb der nuxt-security contentSecurityPolicy-Konfiguration, nicht in separaten routeRules.

Compliance-Relevanz

PCI DSS 4.0 (Anforderung 11.6.1) fordert dauerhaftes Monitoring von Security-Policies auf Zahlungsseiten. Die Reporting API liefert automatische Berichte über Verstöße. NIS2 (Artikel 21) verlangt Incident-Detection- und Response-Mechanismen — Browser-Reports ermöglichen frühzeitige Erkennung von XSS-Versuchen und Policy-Verstößen. BSI IT-Grundschutz (DER.1) fordert die Detektion sicherheitsrelevanter Ereignisse. Der Wolf-Agents Web Security Check bewertet die Reporting-Konfiguration mit bis zu 4 Punkten.

Wie steht Ihre Domain bei Reporting API?

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