From 63e1f63486ce4642ab5570374f70f53798ee26e9 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Mon, 14 Nov 2022 19:50:19 +0100 Subject: [PATCH] Add `DisableXsrfCheck` attribute to opt out of the automated XSRF validation --- .../files/lib/http/middleware/Xsrf.class.php | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/wcfsetup/install/files/lib/http/middleware/Xsrf.class.php b/wcfsetup/install/files/lib/http/middleware/Xsrf.class.php index 028cc094b7..94b8fabd09 100644 --- a/wcfsetup/install/files/lib/http/middleware/Xsrf.class.php +++ b/wcfsetup/install/files/lib/http/middleware/Xsrf.class.php @@ -56,18 +56,33 @@ final class Xsrf implements MiddlewareInterface $request->getMethod() !== 'GET' && $request->getMethod() !== 'HEAD' && $this->requestHandler->getActiveRequest() - && \is_subclass_of($this->requestHandler->getActiveRequest()->getClassName(), RequestHandlerInterface::class) ) { - if (!$this->validateXsrfToken($this->requestHandler->getActiveRequest(), $hasValidXsrfToken)) { - throw new InvalidSecurityTokenException(); - } + $this->assertHasValidXsrfToken($this->requestHandler->getActiveRequest(), $hasValidXsrfToken); } return $handler->handle($request); } - private function validateXsrfToken(Request $request, $hasValidXsrfToken): bool + private function assertHasValidXsrfToken(Request $request, $hasValidXsrfToken): void { - return $hasValidXsrfToken; + if (!\is_subclass_of($request->getClassName(), RequestHandlerInterface::class)) { + // Skip the XSRF check for legacy controllers. + return; + } + + $reflectionClass = new \ReflectionClass($request->getClassName()); + if ($reflectionClass->getAttributes('DisableXsrfCheck') !== []) { + // Controller has opted out of the XSRF check. + return; + } + + if (!$hasValidXsrfToken) { + throw new InvalidSecurityTokenException(); + } } } + +#[\Attribute(\Attribute::TARGET_CLASS)] +final class DisableXsrfCheck +{ +} -- 2.20.1