Reporting API in Spring Boot

Browser-Reports per OncePerRequestFilter empfangen -- mit Reporting-Endpoints, CSP-report-to-Integration und eigenem Report-Receiver.

Spring Boot · Schritt für Schritt

Reporting API in Spring Boot

Die Reporting API ermöglicht es Browsern, Sicherheitsverletzungen (CSP-Violations, Deprecation Warnings, Crashes) an einen Endpoint zu melden. Der Reporting-Endpoints-Header definiert, wohin Reports gesendet werden. Die Reporting API ist mit 4 von 166 Punkten im Wolf-Agents Web Security Check bewertet.

Spring Security bietet keine eingebaute DSL für Reporting-Endpoints. Sie benoetigen einen OncePerRequestFilter, der die Header Reporting-Endpoints und Report-To setzt, sowie einen Controller-Endpoint, der die Reports empfaengt und verarbeitet.

1Schritt 1 von 3

Reporting-Endpoints konfigurieren

Erstellen Sie einen OncePerRequestFilter, der den Reporting-Endpoints-Header (neue API) und Report-To (Legacy-Kompatibilität) auf jede Response setzt. Definieren Sie benannte Endpoints, die Sie in CSP report-to referenzieren können.

ReportingApiFilter.javaProduktiv
// ReportingApiFilter.java
package com.example.filter;

import jakarta.servlet.*;
import jakarta.servlet.http.*;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.stereotype.Component;

@Component
public class ReportingApiFilter
        extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain filterChain) throws Exception {

        // Reporting-Endpoints (neue API)
        response.setHeader(
            "Reporting-Endpoints",
            "csp-endpoint="https://example.com/api/reports/csp", "
            + "default="https://example.com/api/reports"");

        // Report-To (Legacy, fuer aeltere Browser)
        response.setHeader(
            "Report-To",
            "{"group":"csp-endpoint","
            + ""max_age":86400,"
            + ""endpoints":[{"url":"
            + ""https://example.com/api/reports/csp"}]}");

        filterChain.doFilter(request, response);
    }
}
Zwei Header für Kompatibilität

Setzen Sie beide Header: Reporting-Endpoints (neue Reporting API v1) und Report-To (Legacy v0). Moderne Browser nutzen die neue API, aeltere Browser die Legacy-Version.

2Schritt 2 von 3

CSP-Reporting integrieren

Verbinden Sie die CSP-Konfiguration mit den Reporting-Endpoints. Verwenden Sie report-to (neue API) und report-uri (Legacy-Fallback) in der CSP-Direktive. So werden CSP-Violations automatisch an Ihren Endpoint gemeldet.

SecurityConfig.javaProduktiv
// SecurityConfig.java -- CSP mit report-to
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http)
        throws Exception {
    http.headers(headers -> headers
        .contentSecurityPolicy(csp -> csp
            .policyDirectives(
                "default-src 'self'; "
                + "script-src 'self'; "
                + "report-to csp-endpoint; "
                + "report-uri /api/reports/csp"))
    );
    return http.build();
}
Der Wolf-Agents Web Security Check prüft Reporting-Header automatisch und bewertet sie mit bis zu 4 Punkten.
3Schritt 3 von 3

Report-Empfangs-Endpoint

Erstellen Sie einen Controller, der die Browser-Reports empfaengt. CSP-Reports kommen mit Content-Type application/csp-report, Reporting-API-Reports mit application/reports+json. Loggen Sie die Reports für Analyse und Monitoring.

ReportController.javaProduktiv
// ReportController.java -- Reports empfangen
@RestController
@RequestMapping("/api/reports")
public class ReportController {

    private static final Logger log =
        LoggerFactory.getLogger(ReportController.class);

    @PostMapping(value = "/csp",
        consumes = "application/csp-report")
    public ResponseEntity<Void> cspReport(
            @RequestBody String report) {
        log.warn("CSP Violation: {}", report);
        return ResponseEntity.accepted().build();
    }

    @PostMapping(value = "/",
        consumes = "application/reports+json")
    public ResponseEntity<Void> genericReport(
            @RequestBody String report) {
        log.info("Browser Report: {}", report);
        return ResponseEntity.accepted().build();
    }
}
4Verifizierung

Reporting-Header verifizieren

Prüfen Sie die Reporting-Header per curl. Beide Header -- Reporting-Endpoints und Report-To -- müssen gesetzt sein.

TerminalVerifizierung
# Reporting-Endpoints pruefen
curl -sI http://localhost:8080 | grep -i reporting

# Erwartete Ausgabe:
reporting-endpoints: csp-endpoint="https://example.com/api/reports/csp", default="https://example.com/api/reports"
report-to: {"group":"csp-endpoint","max_age":86400,"endpoints":[{"url":"https://example.com/api/reports/csp"}]}

Häufige Fehler bei der Reporting API in Spring Boot

Report-Endpoint nicht in SecurityFilterChain freigegeben

Der Report-Empfangs-Endpoint (/api/reports/**) muss per permitAll() freigegeben werden. Browser senden Reports ohne Authentifizierung -- ein 401/403 fuehrt zu verlorenen Reports.

CSP report-to Name stimmt nicht mit Reporting-Endpoints ueberein

Der Name in report-to csp-endpoint muss exakt mit dem Namen im Reporting-Endpoints-Header uebereinstimmen. Gross-/Kleinschreibung und Bindestriche beachten.

Content-Type application/csp-report nicht registriert

Spring Boot erkennt application/csp-report nicht standardmaessig. Verwenden Sie consumes = "application/csp-report" im @PostMapping und @RequestBody String für den Report-Body.

Compliance-Relevanz

Die Reporting API ermöglicht kontinuierliches Security-Monitoring und ist für proaktive Sicherheitsueberwachung essentiell.

PCI DSS 4.0 -- Requirement 11.6.1 fordert Monitoring-Mechanismen für Sicherheitsheader-Violations.
NIS2 -- Art. 21(b) fordert Incident Handling -- automatische Violation-Reports ermöglichen fruehe Erkennung.
BSI -- SYS.1.1 fordert zentrale Protokollierung sicherheitsrelevanter Ereignisse.

Wie steht Ihre Domain bei Reporting API?

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