Skip to content

Commit

Permalink
[11.x] Enhance malformed request handling (#50735)
Browse files Browse the repository at this point in the history
* Convert SuspiciousOperationException to BadRequestHttpException

This is suggested per https://github.com/symfony/symfony/blob/7.1/src/Symfony/Component/HttpFoundation/Exception/RequestExceptionInterface.php

* Update existing test on SuspiciousOperationException handling

* Add integration test for malformed requests

* Return 400 code on all exceptions extending RequestExceptionInterface
  • Loading branch information
jnoordsij authored Mar 25, 2024
1 parent 57610f7 commit bf02fde
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
7 changes: 4 additions & 3 deletions src/Illuminate/Foundation/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@
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;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
Expand Down Expand Up @@ -143,7 +144,7 @@ class Handler implements ExceptionHandlerContract
ModelNotFoundException::class,
MultipleRecordsFoundException::class,
RecordsNotFoundException::class,
SuspiciousOperationException::class,
RequestExceptionInterface::class,
TokenMismatchException::class,
ValidationException::class,
];
Expand Down Expand Up @@ -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 RequestExceptionInterface => new BadRequestHttpException('Bad request.', $e),
$e instanceof RecordsNotFoundException => new NotFoundHttpException('Not found.', $e),
default => $e,
};
Expand Down
6 changes: 3 additions & 3 deletions tests/Foundation/FoundationExceptionsHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions tests/Integration/Foundation/ExceptionHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down

0 comments on commit bf02fde

Please sign in to comment.