From e359ac4eeace6536cc6033e4386267e6eee0a8eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Munsch?= Date: Mon, 23 May 2022 15:02:54 +0200 Subject: [PATCH] Add CSP report URI --- app/Providers/RouteServiceProvider.php | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 9f141d0..be41a7d 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -35,6 +35,8 @@ class RouteServiceProvider extends ServiceProvider { $this->configureRateLimiting(); + $this->cspReportRoute(); + $this->routes(function () { Route::prefix('api') ->middleware('api') @@ -70,4 +72,42 @@ class RouteServiceProvider extends ServiceProvider return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip()); }); } + + /** + * * Register CSP report URI + * + * Put this function inside RouteServiceProvider, + * and call it in RouteServiceProvider::boot + * + * ! Use this in conjonction with kwaadpepper/exception-handler + * + * @return void + */ + private function cspReportRoute() + { + // * CSP REPORT URI, Please add /csp-report to VerifyCsrfToken $except middleware + \Illuminate\Support\Facades\Route::post('/csp-report', function () { + $isCspRequest = request()->header('Content-Type') === 'application/csp-report'; + if (!$isCspRequest or !request()->json('csp-report') or !is_array(request()->json('csp-report'))) { + abort(401); + } + // * Flatten if needed + $cspReport = collect(request()->json('csp-report')) + ->flatMap(function ($v, $k) { + return [$k => is_array($v) ? collect($v)->flatten()->implode(', ') : $v]; + })->all(); + // * Filter array keys + $cspReport = collect(array_intersect_key($cspReport, [ + 'blocked-uri' => '', 'document-uri' => '', 'original-policy' => '', + 'referrer' => '', 'violated-directive' => '' + ])); + report(new \Illuminate\Http\Client\HttpClientException(sprintf( + "CSP REPORT for %s : \n %s", + $cspReport->get('document-uri'), + $cspReport->implode("\n") + ))); + })->middleware('throttle:5,2') + ->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class) + ->name('cspReportUri'); + } }