From c60c7ab85362be13cc2a11ad1a118c9c99a324c4 Mon Sep 17 00:00:00 2001 From: Jesper Noordsij Date: Tue, 12 Mar 2024 14:39:05 +0100 Subject: [PATCH 1/4] Convert SuspiciousOperationException to BadRequestHttpException This is suggested per https://github.com/symfony/symfony/blob/7.1/src/Symfony/Component/HttpFoundation/Exception/RequestExceptionInterface.php --- src/Illuminate/Foundation/Exceptions/Handler.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Exceptions/Handler.php b/src/Illuminate/Foundation/Exceptions/Handler.php index d3111a462b5c..3d46d0330aa2 100644 --- a/src/Illuminate/Foundation/Exceptions/Handler.php +++ b/src/Illuminate/Foundation/Exceptions/Handler.php @@ -42,6 +42,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse as SymfonyRedirectResponse; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -630,7 +631,7 @@ protected function prepareException(Throwable $e) ), $e instanceof AuthorizationException && ! $e->hasStatus() => new AccessDeniedHttpException($e->getMessage(), $e), $e instanceof TokenMismatchException => new HttpException(419, $e->getMessage(), $e), - $e instanceof SuspiciousOperationException => new NotFoundHttpException('Bad hostname provided.', $e), + $e instanceof SuspiciousOperationException => new BadRequestHttpException('Bad request.', $e), $e instanceof RecordsNotFoundException => new NotFoundHttpException('Not found.', $e), default => $e, }; From 2f582da209eec22e8b96f4af218ffe7b64142e06 Mon Sep 17 00:00:00 2001 From: Jesper Noordsij Date: Thu, 14 Mar 2024 09:38:48 +0100 Subject: [PATCH 2/4] Update existing test on SuspiciousOperationException handling --- tests/Foundation/FoundationExceptionsHandlerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Foundation/FoundationExceptionsHandlerTest.php b/tests/Foundation/FoundationExceptionsHandlerTest.php index 51ecd52b16c0..70ac2a96f9c9 100644 --- a/tests/Foundation/FoundationExceptionsHandlerTest.php +++ b/tests/Foundation/FoundationExceptionsHandlerTest.php @@ -359,15 +359,15 @@ function ($argument) use (&$argumentActual) { $this->assertEquals($argumentExpected, $argumentActual); } - public function testSuspiciousOperationReturns404WithoutReporting() + public function testSuspiciousOperationReturns400WithoutReporting() { $this->config->shouldReceive('get')->with('app.debug', null)->once()->andReturn(true); $this->request->shouldReceive('expectsJson')->once()->andReturn(true); $response = $this->handler->render($this->request, new SuspiciousOperationException('Invalid method override "__CONSTRUCT"')); - $this->assertEquals(404, $response->getStatusCode()); - $this->assertStringContainsString('"message": "Bad hostname provided."', $response->getContent()); + $this->assertEquals(400, $response->getStatusCode()); + $this->assertStringContainsString('"message": "Bad request."', $response->getContent()); $logger = m::mock(LoggerInterface::class); $this->container->instance(LoggerInterface::class, $logger); From fd7eb617193e333696b18dfbb8c753a7bb079d10 Mon Sep 17 00:00:00 2001 From: Jesper Noordsij Date: Thu, 14 Mar 2024 09:39:13 +0100 Subject: [PATCH 3/4] Add integration test for malformed requests --- .../Foundation/ExceptionHandlerTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Integration/Foundation/ExceptionHandlerTest.php b/tests/Integration/Foundation/ExceptionHandlerTest.php index d13a74f4122b..499751337c7a 100644 --- a/tests/Integration/Foundation/ExceptionHandlerTest.php +++ b/tests/Integration/Foundation/ExceptionHandlerTest.php @@ -124,6 +124,21 @@ public function testItHasFallbackErrorMessageForUnknownStatusCodes() ]); } + public function testItReturns400CodeOnMalformedRequests() + { + // HTTP request... + $this->post('test-route', ['_method' => '__construct']) + ->assertStatus(400) + ->assertSeeText('Bad Request'); // see https://github.com/symfony/symfony/blob/1d439995eb6d780531b97094ff5fa43e345fc42e/src/Symfony/Component/ErrorHandler/Resources/views/error.html.php#L12 + + // JSON request... + $this->postJson('test-route', ['_method' => '__construct']) + ->assertStatus(400) + ->assertExactJson([ + 'message' => 'Bad request.', + ]); + } + #[DataProvider('exitCodesProvider')] public function testItReturnsNonZeroExitCodesForUncaughtExceptions($providers, $successful) { From f9cbef4f276fe805d8cdb6bec97693c7e1224149 Mon Sep 17 00:00:00 2001 From: Jesper Noordsij Date: Sat, 16 Mar 2024 16:54:46 +0100 Subject: [PATCH 4/4] Return 400 code on all exceptions extending RequestExceptionInterface --- src/Illuminate/Foundation/Exceptions/Handler.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Foundation/Exceptions/Handler.php b/src/Illuminate/Foundation/Exceptions/Handler.php index 3d46d0330aa2..791f2cc69812 100644 --- a/src/Illuminate/Foundation/Exceptions/Handler.php +++ b/src/Illuminate/Foundation/Exceptions/Handler.php @@ -38,7 +38,7 @@ use Symfony\Component\Console\Application as ConsoleApplication; use Symfony\Component\Console\Exception\CommandNotFoundException; use Symfony\Component\ErrorHandler\ErrorRenderer\HtmlErrorRenderer; -use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException; +use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface; use Symfony\Component\HttpFoundation\RedirectResponse as SymfonyRedirectResponse; use Symfony\Component\HttpFoundation\Response as SymfonyResponse; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; @@ -144,7 +144,7 @@ class Handler implements ExceptionHandlerContract ModelNotFoundException::class, MultipleRecordsFoundException::class, RecordsNotFoundException::class, - SuspiciousOperationException::class, + RequestExceptionInterface::class, TokenMismatchException::class, ValidationException::class, ]; @@ -631,7 +631,7 @@ protected function prepareException(Throwable $e) ), $e instanceof AuthorizationException && ! $e->hasStatus() => new AccessDeniedHttpException($e->getMessage(), $e), $e instanceof TokenMismatchException => new HttpException(419, $e->getMessage(), $e), - $e instanceof SuspiciousOperationException => new BadRequestHttpException('Bad request.', $e), + $e instanceof RequestExceptionInterface => new BadRequestHttpException('Bad request.', $e), $e instanceof RecordsNotFoundException => new NotFoundHttpException('Not found.', $e), default => $e, };