Skip to content

Commit cee5528

Browse files
authored
Merge pull request #6292 from kenjis/fix-Security-derandomize
fix: Security::derandomize() may cause hex2bin() error
2 parents c1bac7e + 38c8cbf commit cee5528

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

system/Security/Security.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
use Config\Cookie as CookieConfig;
2222
use Config\Security as SecurityConfig;
2323
use Config\Services;
24+
use ErrorException;
25+
use InvalidArgumentException;
2426
use LogicException;
2527

2628
/**
@@ -278,8 +280,13 @@ public function verify(RequestInterface $request)
278280
}
279281

280282
$postedToken = $this->getPostedToken($request);
281-
$token = ($postedToken !== null && $this->tokenRandomize)
282-
? $this->derandomize($postedToken) : $postedToken;
283+
284+
try {
285+
$token = ($postedToken !== null && $this->tokenRandomize)
286+
? $this->derandomize($postedToken) : $postedToken;
287+
} catch (InvalidArgumentException $e) {
288+
$token = null;
289+
}
283290

284291
// Do the tokens match?
285292
if (! isset($token, $this->hash) || ! hash_equals($this->hash, $token)) {
@@ -359,13 +366,20 @@ protected function randomize(string $hash): string
359366

360367
/**
361368
* Derandomize the token.
369+
*
370+
* @throws InvalidArgumentException "hex2bin(): Hexadecimal input string must have an even length"
362371
*/
363372
protected function derandomize(string $token): string
364373
{
365374
$key = substr($token, -static::CSRF_HASH_BYTES * 2);
366375
$value = substr($token, 0, static::CSRF_HASH_BYTES * 2);
367376

368-
return bin2hex(hex2bin($value) ^ hex2bin($key));
377+
try {
378+
return bin2hex(hex2bin($value) ^ hex2bin($key));
379+
} catch (ErrorException $e) {
380+
// "hex2bin(): Hexadecimal input string must have an even length"
381+
throw new InvalidArgumentException($e->getMessage());
382+
}
369383
}
370384

371385
/**

tests/system/Security/SecurityCSRFSessionRandomizeTokenTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,21 @@ public function testCSRFVerifyPostThrowsExceptionOnNoMatch()
141141
$security->verify($request);
142142
}
143143

144+
public function testCSRFVerifyPostInvalidToken()
145+
{
146+
$this->expectException(SecurityException::class);
147+
$this->expectExceptionMessage('The action you requested is not allowed.');
148+
149+
$_SERVER['REQUEST_METHOD'] = 'POST';
150+
$_POST['csrf_test_name'] = '!';
151+
152+
$request = new IncomingRequest(new MockAppConfig(), new URI('http://badurl.com'), null, new UserAgent());
153+
154+
$security = new Security(new MockAppConfig());
155+
156+
$security->verify($request);
157+
}
158+
144159
public function testCSRFVerifyPostReturnsSelfOnMatch()
145160
{
146161
$_SERVER['REQUEST_METHOD'] = 'POST';

0 commit comments

Comments
 (0)