Skip to content

Commit f94b76f

Browse files
committed
bug #41737 [Security] Fix special char used to create cache key (jderusse)
This PR was merged into the 5.3 branch. Discussion ---------- [Security] Fix special char used to create cache key | Q | A | ------------- | --- | Branch? | 5.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - The remember Me token's `series` property might contains special chars: because it has been generated with `$series = base64_encode(random_bytes(64));`. When using this identifier to create cache items, users get Exception `Cache key "foo+bar/baz==" contains reserved characters "{}()/\@:".` This PR sanitize the property before using it as cache key Commits ------- fc9e9ff7a1 Fix special char used to create cache key
2 parents 8fb2dbb + a70b131 commit f94b76f

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

Authentication/RememberMe/CacheTokenVerifier.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ public function verifyToken(PersistentTokenInterface $token, string $tokenValue)
4343
return true;
4444
}
4545

46-
if (!$this->cache->hasItem($this->cacheKeyPrefix.$token->getSeries())) {
46+
$cacheKey = $this->getCacheKey($token);
47+
if (!$this->cache->hasItem($cacheKey)) {
4748
return false;
4849
}
4950

50-
$item = $this->cache->getItem($this->cacheKeyPrefix.$token->getSeries());
51+
$item = $this->cache->getItem($cacheKey);
5152
$outdatedToken = $item->get();
5253

5354
return hash_equals($outdatedToken, $tokenValue);
@@ -60,9 +61,14 @@ public function updateExistingToken(PersistentTokenInterface $token, string $tok
6061
{
6162
// When a token gets updated, persist the outdated token for $outdatedTokenTtl seconds so we can
6263
// still accept it as valid in verifyToken
63-
$item = $this->cache->getItem($this->cacheKeyPrefix.$token->getSeries());
64+
$item = $this->cache->getItem($this->getCacheKey($token));
6465
$item->set($token->getTokenValue());
6566
$item->expiresAfter($this->outdatedTokenTtl);
6667
$this->cache->save($item);
6768
}
69+
70+
private function getCacheKey(PersistentTokenInterface $token): string
71+
{
72+
return $this->cacheKeyPrefix.rawurlencode($token->getSeries());
73+
}
6874
}

Tests/Authentication/RememberMe/CacheTokenVerifierTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,22 @@ class CacheTokenVerifierTest extends TestCase
2121
public function testVerifyCurrentToken()
2222
{
2323
$verifier = new CacheTokenVerifier(new ArrayAdapter());
24-
$token = new PersistentToken('class', 'user', 'series1', 'value', new \DateTime());
24+
$token = new PersistentToken('class', 'user', 'series1@special:chars=/', 'value', new \DateTime());
2525
$this->assertTrue($verifier->verifyToken($token, 'value'));
2626
}
2727

2828
public function testVerifyFailsInvalidToken()
2929
{
3030
$verifier = new CacheTokenVerifier(new ArrayAdapter());
31-
$token = new PersistentToken('class', 'user', 'series1', 'value', new \DateTime());
31+
$token = new PersistentToken('class', 'user', 'series1@special:chars=/', 'value', new \DateTime());
3232
$this->assertFalse($verifier->verifyToken($token, 'wrong-value'));
3333
}
3434

3535
public function testVerifyOutdatedToken()
3636
{
3737
$verifier = new CacheTokenVerifier(new ArrayAdapter());
38-
$outdatedToken = new PersistentToken('class', 'user', 'series1', 'value', new \DateTime());
39-
$newToken = new PersistentToken('class', 'user', 'series1', 'newvalue', new \DateTime());
38+
$outdatedToken = new PersistentToken('class', 'user', 'series1@special:chars=/', 'value', new \DateTime());
39+
$newToken = new PersistentToken('class', 'user', 'series1@special:chars=/', 'newvalue', new \DateTime());
4040
$verifier->updateExistingToken($outdatedToken, 'newvalue', new \DateTime());
4141
$this->assertTrue($verifier->verifyToken($newToken, 'value'));
4242
}

0 commit comments

Comments
 (0)