From dc71f47af46abd85dc35ef38ef719ffe9663c395 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 3 Nov 2022 17:56:50 +0100 Subject: [PATCH] Transparently decode JSON requests --- .../lib/http/middleware/JsonBody.class.php | 57 +++++++++++++++++++ .../system/request/RequestHandler.class.php | 2 + 2 files changed, 59 insertions(+) create mode 100644 wcfsetup/install/files/lib/http/middleware/JsonBody.class.php diff --git a/wcfsetup/install/files/lib/http/middleware/JsonBody.class.php b/wcfsetup/install/files/lib/http/middleware/JsonBody.class.php new file mode 100644 index 0000000000..da29018d6d --- /dev/null +++ b/wcfsetup/install/files/lib/http/middleware/JsonBody.class.php @@ -0,0 +1,57 @@ + + * @package WoltLabSuite\Core\Http\Middleware + * @since 6.0 + */ +final class JsonBody implements MiddlewareInterface +{ + public const HAS_VALID_JSON_ATTRIBUTE = self::class . "\0hasValidJson"; + + private const EXPECTED_CONTENT_TYPE = 'application/json'; + + /** + * @inheritDoc + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $hasValidJson = false; + if ( + $request->getHeaderLine('content-type') === self::EXPECTED_CONTENT_TYPE + || \str_starts_with($request->getHeaderLine('content-type'), self::EXPECTED_CONTENT_TYPE) + ) { + try { + $data = JSON::decode($request->getBody()); + } catch (SystemException $e) { + return new TextResponse('Failed to decode the request body.', 400); + } + + $request = $request->withParsedBody($data); + + $hasValidJson = true; + } + + $request = $request->withAttribute( + self::HAS_VALID_JSON_ATTRIBUTE, + $hasValidJson, + ); + + return $handler->handle($request); + } +} diff --git a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php index 89264e9650..bf11b184c8 100644 --- a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php @@ -19,6 +19,7 @@ use wcf\http\middleware\EnforceAcpAuthentication; use wcf\http\middleware\EnforceCacheControlPrivate; use wcf\http\middleware\EnforceFrameOptions; use wcf\http\middleware\HandleStartupErrors; +use wcf\http\middleware\JsonBody; use wcf\http\middleware\PreventMimeSniffing; use wcf\http\middleware\Xsrf; use wcf\http\Pipeline; @@ -108,6 +109,7 @@ final class RequestHandler extends SingletonFactory new CheckForEnterpriseNonOwnerAccess(), new CheckForExpiredAppEvaluation(), new CheckForOfflineMode(), + new JsonBody(), ]); $response = $pipeline->process($psrRequest, $this->getActiveRequest()); -- 2.20.1