Skip to content

Commit 334db6c

Browse files
committed
Merge branch 'sw-26662/thorw-csrf-exception' into '5.7'
SW-26662 - throw csrf exception See merge request shopware/5/product/shopware!800
2 parents a25fe81 + 5959191 commit 334db6c

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

engine/Shopware/Components/CSRFTokenValidator.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public function checkFrontendTokenValidation(Enlight_Event_EventArgs $args)
161161
}
162162

163163
if (!$this->checkRequest($request, $response)) {
164+
$this->regenerateToken($request, $response);
164165
throw new CSRFTokenValidationException(sprintf('The provided X-CSRF-Token for path "%s" is invalid. Please go back, reload the page and try again.', $request->getRequestUri()));
165166
}
166167

@@ -199,15 +200,17 @@ private function checkRequest(Request $request, Response $response): bool
199200

200201
$token = $this->container->get('session')->get($name);
201202

202-
$requestToken = $request->get(self::CSRF_TOKEN_ARGUMENT, $request->headers->get(self::CSRF_TOKEN_HEADER));
203+
if (!\is_string($token)) {
204+
return false;
205+
}
203206

204-
$isValidToken = hash_equals($token, $requestToken);
207+
$requestToken = $request->get(self::CSRF_TOKEN_ARGUMENT, $request->headers->get(self::CSRF_TOKEN_HEADER));
205208

206-
if (!$isValidToken) {
207-
$this->regenerateToken($request, $response);
209+
if (!\is_string($requestToken)) {
210+
return false;
208211
}
209212

210-
return $isValidToken;
213+
return hash_equals($token, $requestToken);
211214
}
212215

213216
/**

tests/Functional/Components/CSRFTokenValidatorTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public function testFrontendTokenIsValid(): void
8585

8686
$tokenValidator->checkFrontendTokenValidation($enlightEventArgs);
8787

88+
static::assertNotNull($this->getContainer()->get('session')->get('__csrf_token-1'));
8889
static::assertTrue($incomingRequest->getAttribute('isValidated'));
8990
}
9091

@@ -114,8 +115,60 @@ public function testFrontendTokenValidationThrowsError(): void
114115
static::assertInstanceOf(CSRFTokenValidationException::class, $e);
115116
}
116117

118+
static::assertNotNull($this->getContainer()->get('session')->get('__csrf_token-1'));
117119
static::assertNotEquals($token, $this->getContainer()->get('session')->get('__csrf_token-1'));
118120
}
121+
122+
public function testCsrfExceptionIsThrownWhenNoSession(): void
123+
{
124+
$tokenValidator = $this->getContainer()->get(CSRFTokenValidator::class);
125+
$this->getContainer()->get(ContextServiceInterface::class)->createShopContext(1);
126+
127+
$controller = new MockController();
128+
$incomingRequest = new Enlight_Controller_Request_RequestTestCase();
129+
$incomingResponse = new Enlight_Controller_Response_ResponseTestCase();
130+
$incomingRequest->setActionName(self::EXISTING_ACTION_NAME);
131+
$incomingRequest->setParam(CSRFTokenValidator::CSRF_TOKEN_ARGUMENT, 'NOT_FITTING');
132+
$controller->setRequest($incomingRequest);
133+
$controller->setResponse($incomingResponse);
134+
$enlightEventArgs = new Enlight_Event_EventArgs([
135+
'subject' => $controller,
136+
]);
137+
138+
try {
139+
$tokenValidator->checkFrontendTokenValidation($enlightEventArgs);
140+
} catch (Throwable $e) {
141+
static::assertInstanceOf(CSRFTokenValidationException::class, $e);
142+
}
143+
144+
static::assertNotNull($this->getContainer()->get('session')->get('__csrf_token-1'));
145+
}
146+
147+
public function testCsrfExceptionIsThrownWhenNoRequestCsrfIsSet(): void
148+
{
149+
$tokenValidator = $this->getContainer()->get(CSRFTokenValidator::class);
150+
$this->getContainer()->get(ContextServiceInterface::class)->createShopContext(1);
151+
$createRequest = new Enlight_Controller_Request_RequestTestCase();
152+
$createResponse = new Enlight_Controller_Response_ResponseTestCase();
153+
$tokenValidator->regenerateToken($createRequest, $createResponse);
154+
155+
$controller = new MockController();
156+
$incomingRequest = new Enlight_Controller_Request_RequestTestCase();
157+
$incomingResponse = new Enlight_Controller_Response_ResponseTestCase();
158+
$controller->setRequest($incomingRequest);
159+
$controller->setResponse($incomingResponse);
160+
$enlightEventArgs = new Enlight_Event_EventArgs([
161+
'subject' => $controller,
162+
]);
163+
164+
try {
165+
$tokenValidator->checkFrontendTokenValidation($enlightEventArgs);
166+
} catch (Throwable $e) {
167+
static::assertInstanceOf(CSRFTokenValidationException::class, $e);
168+
}
169+
170+
static::assertNotNull($this->getContainer()->get('session')->get('__csrf_token-1'));
171+
}
119172
}
120173

121174
class MockController extends Enlight_Controller_Action implements CSRFGetProtectionAware

0 commit comments

Comments
 (0)