diff --git a/packages/router/src/PreventCrossSiteRequestsMiddleware.php b/packages/router/src/PreventCrossSiteRequestsMiddleware.php index 8307d00bc..7435a2587 100644 --- a/packages/router/src/PreventCrossSiteRequestsMiddleware.php +++ b/packages/router/src/PreventCrossSiteRequestsMiddleware.php @@ -15,11 +15,10 @@ * * - Safe HTTP methods are always allowed * - Requests from same-origin or same-site are allowed - * - Cross-site requests that aren't navigation are blocked + * - Cross-site requests using unsafe methods are blocked * - Requests without Sec-Fetch-Site headers are blocked * * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Site - * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode * @see https://web.dev/articles/fetch-metadata */ #[Priority(Priority::FRAMEWORK - 8)] @@ -59,18 +58,12 @@ private function shouldValidate(Request $request): bool private function isValidRequest(Request $request): bool { $secFetchSite = SecFetchSite::tryFrom($request->headers->get('sec-fetch-site', default: '')); - $secFetchMode = SecFetchMode::tryFrom($request->headers->get('sec-fetch-mode', default: '')); // prevent the request if there is no `sec-fetch-site` header if ($secFetchSite === null) { return false; } - // allow cross-site only on navigation requests - if ($secFetchSite === SecFetchSite::CROSS_SITE && $secFetchMode === SecFetchMode::NAVIGATE) { - return true; - } - // same origin, same site and user-originated requests are always allowed return $secFetchSite !== SecFetchSite::CROSS_SITE; } diff --git a/tests/Integration/Router/PreventCrossSiteRequestsMiddlewareTest.php b/tests/Integration/Router/PreventCrossSiteRequestsMiddlewareTest.php index 3f568d178..e7ae7bb14 100644 --- a/tests/Integration/Router/PreventCrossSiteRequestsMiddlewareTest.php +++ b/tests/Integration/Router/PreventCrossSiteRequestsMiddlewareTest.php @@ -67,14 +67,14 @@ public function post_with_none_site_is_allowed(): void } #[Test] - public function post_with_cross_site_navigation_is_allowed(): void + public function post_with_cross_site_navigation_is_blocked(): void { $this->http ->post('/test', headers: [ 'sec-fetch-site' => SecFetchSite::CROSS_SITE, 'sec-fetch-mode' => SecFetchMode::NAVIGATE, ]) - ->assertOk(); + ->assertForbidden(); } #[Test]