From 9ed976fafb26f811a82b1eb24ae3c462385c178d Mon Sep 17 00:00:00 2001 From: Audun Rundberg Date: Sun, 3 May 2026 10:09:03 +0200 Subject: [PATCH 1/2] fix: exclude all CSRF middleware variants from reports route In Laravel 13, VerifyCsrfToken is deprecated and PreventRequestForgery is the new base class (with ValidateCsrfToken extending it). Exclude all three so the endpoint works regardless of which variant the host app uses. Closes #2 --- routes/reporting-api.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/routes/reporting-api.php b/routes/reporting-api.php index 8fca677..7c82059 100644 --- a/routes/reporting-api.php +++ b/routes/reporting-api.php @@ -1,9 +1,11 @@ middleware(['throttle:'.config('reporting-api.throttle', '60,1')]) - ->withoutMiddleware([VerifyCsrfToken::class]); + ->withoutMiddleware([VerifyCsrfToken::class, ValidateCsrfToken::class, PreventRequestForgery::class]); From af1bf0b2d4b28b9b86a00912a1ae965e07d7d6ec Mon Sep 17 00:00:00 2001 From: Audun Rundberg Date: Sun, 3 May 2026 10:11:39 +0200 Subject: [PATCH 2/2] fix: use PHP string interpolation in log messages PSR-3 placeholder syntax ({directive}, {url}) is not interpolated by Monolog's LineFormatter by default, so placeholders appeared literally in log output. Replaced with PHP double-quoted string interpolation. Closes #3 Co-Authored-By: Claude Sonnet 4.6 --- src/Listeners/LogCspViolation.php | 4 +--- src/Listeners/LogReport.php | 4 +--- tests/Unit/Listeners/LogCspViolationTest.php | 4 +++- tests/Unit/Listeners/LogReportTest.php | 4 +++- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Listeners/LogCspViolation.php b/src/Listeners/LogCspViolation.php index 22708e4..5bd8140 100644 --- a/src/Listeners/LogCspViolation.php +++ b/src/Listeners/LogCspViolation.php @@ -21,9 +21,7 @@ public function handle(CspViolationReceived $event): void return; } - Log::channel($this->channel)->warning('CSP violation: {directive} blocked {url}', [ - 'directive' => $report->body->effectiveDirective, - 'url' => $report->body->blockedURL, + Log::channel($this->channel)->warning("CSP violation: {$report->body->effectiveDirective} blocked {$report->body->blockedURL}", [ 'page' => $report->url, ]); } diff --git a/src/Listeners/LogReport.php b/src/Listeners/LogReport.php index 8917e8e..90970a0 100644 --- a/src/Listeners/LogReport.php +++ b/src/Listeners/LogReport.php @@ -18,9 +18,7 @@ public function handle(ReportEvent $event): void return; } - Log::channel($this->channel)->info('{type} report received at {url}', [ - 'type' => $report->type, - 'url' => $report->url, + Log::channel($this->channel)->info("{$report->type} report received at {$report->url}", [ 'report' => $event->getRawReport(), ]); } diff --git a/tests/Unit/Listeners/LogCspViolationTest.php b/tests/Unit/Listeners/LogCspViolationTest.php index d65c1ed..0d279e9 100644 --- a/tests/Unit/Listeners/LogCspViolationTest.php +++ b/tests/Unit/Listeners/LogCspViolationTest.php @@ -26,7 +26,9 @@ public function test_logs_warning_for_csp_violation(): void (new LogCspViolation)->handle($event); - $spy->shouldHaveReceived('warning')->once(); + $spy->shouldHaveReceived('warning') + ->once() + ->with('CSP violation: script-src blocked https://evil.example/script.js', ['page' => 'https://example.test/page']); } public function test_skips_logging_when_excluded(): void diff --git a/tests/Unit/Listeners/LogReportTest.php b/tests/Unit/Listeners/LogReportTest.php index e7ca09f..4f679df 100644 --- a/tests/Unit/Listeners/LogReportTest.php +++ b/tests/Unit/Listeners/LogReportTest.php @@ -26,7 +26,9 @@ public function test_logs_info_for_any_report(): void (new LogReport)->handle($event); - $spy->shouldHaveReceived('info')->once(); + $spy->shouldHaveReceived('info') + ->once() + ->with('deprecation report received at https://example.test/page', \Mockery::type('array')); } public function test_skips_logging_when_excluded(): void