Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5be0da2

Browse filesBrowse files
committed
Hiding userFqcn in RememberMe cookie
1 parent e348b70 commit 5be0da2
Copy full SHA for 5be0da2

File tree

7 files changed

+28
-23
lines changed
Filter options

7 files changed

+28
-23
lines changed

‎src/Symfony/Component/Security/Http/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/CHANGELOG.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ CHANGELOG
33

44
7.3
55
---
6-
6+
* Rename property userFqcn to userFqcnHash, remove method getUserFqcn, add method getUserFqcnHash.
77
* Add encryption support to `OidcTokenHandler` (JWE)
88

99
7.2

‎src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): U
6767
[$series, $tokenValue] = explode(':', $rememberMeDetails->getValue(), 2);
6868
$persistentToken = $this->tokenProvider->loadTokenBySeries($series);
6969

70-
if ($persistentToken->getUserIdentifier() !== $rememberMeDetails->getUserIdentifier() || $persistentToken->getClass() !== $rememberMeDetails->getUserFqcn()) {
70+
if ($persistentToken->getUserIdentifier() !== $rememberMeDetails->getUserIdentifier() || !hash_equals(RememberMeDetails::computeUserFqcnHash($persistentToken->getClass()), $rememberMeDetails->getUserFqcnHash())) {
7171
throw new AuthenticationException('The cookie\'s hash is invalid.');
7272
}
7373

@@ -89,7 +89,7 @@ public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): U
8989
}
9090

9191
return parent::consumeRememberMeCookie(new RememberMeDetails(
92-
$persistentToken->getClass(),
92+
RememberMeDetails::computeUserFqcnHash($persistentToken->getClass()),
9393
$persistentToken->getUserIdentifier(),
9494
$expires,
9595
$persistentToken->getLastUsed()->getTimestamp().':'.$series.':'.$tokenValue.':'.$persistentToken->getClass()

‎src/Symfony/Component/Security/Http/RememberMe/RememberMeDetails.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/RememberMe/RememberMeDetails.php
+10-5Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class RememberMeDetails
2222
public const COOKIE_DELIMITER = ':';
2323

2424
public function __construct(
25-
private string $userFqcn,
25+
private string $userFqcnHash,
2626
private string $userIdentifier,
2727
private int $expires,
2828
private string $value,
@@ -48,7 +48,12 @@ public static function fromRawCookie(string $rawCookie): self
4848

4949
public static function fromPersistentToken(PersistentToken $persistentToken, int $expires): self
5050
{
51-
return new static($persistentToken->getClass(), $persistentToken->getUserIdentifier(), $expires, $persistentToken->getSeries().':'.$persistentToken->getTokenValue());
51+
return new static(self::computeUserFqcnHash($persistentToken->getClass()), $persistentToken->getUserIdentifier(), $expires, $persistentToken->getSeries().':'.$persistentToken->getTokenValue());
52+
}
53+
54+
public static function computeUserFqcnHash(string $userFqcn): string
55+
{
56+
return hash('sha256', $userFqcn);
5257
}
5358

5459
public function withValue(string $value): self
@@ -59,9 +64,9 @@ public function withValue(string $value): self
5964
return $details;
6065
}
6166

62-
public function getUserFqcn(): string
67+
public function getUserFqcnHash(): string
6368
{
64-
return $this->userFqcn;
69+
return $this->userFqcnHash;
6570
}
6671

6772
public function getUserIdentifier(): string
@@ -82,6 +87,6 @@ public function getValue(): string
8287
public function toString(): string
8388
{
8489
// $userIdentifier is encoded because it might contain COOKIE_DELIMITER, we assume other values don't
85-
return implode(self::COOKIE_DELIMITER, [strtr($this->userFqcn, '\\', '.'), strtr(base64_encode($this->userIdentifier), '+/=', '-_~'), $this->expires, $this->value]);
90+
return implode(self::COOKIE_DELIMITER, [$this->userFqcnHash, strtr(base64_encode($this->userIdentifier), '+/=', '-_~'), $this->expires, $this->value]);
8691
}
8792
}

‎src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/RememberMe/SignatureRememberMeHandler.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function createRememberMeCookie(UserInterface $user): void
4747
$expires = time() + $this->options['lifetime'];
4848
$value = $this->signatureHasher->computeSignatureHash($user, $expires);
4949

50-
$details = new RememberMeDetails($user::class, $user->getUserIdentifier(), $expires, $value);
50+
$details = new RememberMeDetails(RememberMeDetails::computeUserFqcnHash($user::class), $user->getUserIdentifier(), $expires, $value);
5151
$this->createCookie($details);
5252
}
5353

‎src/Symfony/Component/Security/Http/Tests/Authenticator/RememberMeAuthenticatorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Tests/Authenticator/RememberMeAuthenticatorTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public static function provideSupportsData()
6969

7070
public function testAuthenticate()
7171
{
72-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 1, 'secret');
72+
$rememberMeDetails = new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 1, 'secret');
7373
$request = Request::create('/', 'GET', [], ['_remember_me_cookie' => $rememberMeDetails->toString()]);
7474
$passport = $this->authenticator->authenticate($request);
7575

‎src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentRememberMeHandlerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentRememberMeHandlerTest.php
+8-8Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function testClearRememberMeCookie()
6363
->method('deleteTokenBySeries')
6464
->with('series1');
6565

66-
$this->request->cookies->set('REMEMBERME', (new RememberMeDetails(InMemoryUser::class, 'wouter', 0, 'series1:tokenvalue'))->toString());
66+
$this->request->cookies->set('REMEMBERME', (new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 0, 'series1:tokenvalue'))->toString());
6767

6868
$this->handler->clearRememberMeCookie();
6969

@@ -84,7 +84,7 @@ public function testConsumeRememberMeCookieValid()
8484

8585
$this->tokenProvider->expects($this->once())->method('updateToken')->with('series1');
8686

87-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue');
87+
$rememberMeDetails = new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 360, 'series1:tokenvalue');
8888
$this->handler->consumeRememberMeCookie($rememberMeDetails);
8989

9090
// assert that the cookie has been updated with a new base64 encoded token value
@@ -110,7 +110,7 @@ public function testConsumeRememberMeCookieInvalidOwner()
110110
->willReturn(new PersistentToken(InMemoryUser::class, 'wouter', 'series1', 'tokenvalue', new \DateTime('-10 min')))
111111
;
112112

113-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'jeremy', 360, 'series1:tokenvalue');
113+
$rememberMeDetails = new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'jeremy', 360, 'series1:tokenvalue');
114114

115115
$this->expectException(AuthenticationException::class);
116116
$this->expectExceptionMessage('The cookie\'s hash is invalid.');
@@ -125,7 +125,7 @@ public function testConsumeRememberMeCookieInvalidValue()
125125
->willReturn(new PersistentToken(InMemoryUser::class, 'wouter', 'series1', 'tokenvalue', new \DateTime('-10 min')))
126126
;
127127

128-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue:somethingelse');
128+
$rememberMeDetails = new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 360, 'series1:tokenvalue:somethingelse');
129129

130130
$this->expectException(AuthenticationException::class);
131131
$this->expectExceptionMessage('This token was already used. The account is possibly compromised.');
@@ -151,7 +151,7 @@ public function testConsumeRememberMeCookieValidByValidatorWithoutUpdate()
151151
->willReturn(true)
152152
;
153153

154-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:oldTokenValue');
154+
$rememberMeDetails = new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 360, 'series1:oldTokenValue');
155155
$handler->consumeRememberMeCookie($rememberMeDetails);
156156

157157
$this->assertFalse($this->request->attributes->has(ResponseListener::COOKIE_ATTR_NAME));
@@ -168,7 +168,7 @@ public function testConsumeRememberMeCookieInvalidToken()
168168

169169
$this->expectException(CookieTheftException::class);
170170

171-
$this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue'));
171+
$this->handler->consumeRememberMeCookie(new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 360, 'series1:tokenvalue'));
172172
}
173173

174174
public function testConsumeRememberMeCookieExpired()
@@ -183,7 +183,7 @@ public function testConsumeRememberMeCookieExpired()
183183
$this->expectException(AuthenticationException::class);
184184
$this->expectExceptionMessage('The cookie has expired.');
185185

186-
$this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue'));
186+
$this->handler->consumeRememberMeCookie(new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 360, 'series1:tokenvalue'));
187187
}
188188

189189
public function testBase64EncodedTokens()
@@ -196,7 +196,7 @@ public function testBase64EncodedTokens()
196196

197197
$this->tokenProvider->expects($this->once())->method('updateToken')->with('series1');
198198

199-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue');
199+
$rememberMeDetails = new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 360, 'series1:tokenvalue');
200200
$rememberMeDetails = RememberMeDetails::fromRawCookie(base64_encode($rememberMeDetails->toString()));
201201
$this->handler->consumeRememberMeCookie($rememberMeDetails);
202202
}

‎src/Symfony/Component/Security/Http/Tests/RememberMe/SignatureRememberMeHandlerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Tests/RememberMe/SignatureRememberMeHandlerTest.php
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public function testCreateRememberMeCookie()
5757

5858
/** @var Cookie $cookie */
5959
$cookie = $this->request->attributes->get(ResponseListener::COOKIE_ATTR_NAME);
60-
$this->assertEquals(strtr(InMemoryUser::class, '\\', '.').':d291dGVy:'.$expire.':'.$signature, $cookie->getValue());
60+
$this->assertEquals(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class).':d291dGVy:'.$expire.':'.$signature, $cookie->getValue());
6161
}
6262

6363
public function testClearRememberMeCookie()
@@ -77,21 +77,21 @@ public function testConsumeRememberMeCookieValid()
7777
$signature = $this->signatureHasher->computeSignatureHash($user, $expire = time() + 3600);
7878
$this->userProvider->createUser(new InMemoryUser('wouter', null));
7979

80-
$rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', $expire, $signature);
80+
$rememberMeDetails = new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', $expire, $signature);
8181
$this->handler->consumeRememberMeCookie($rememberMeDetails);
8282

8383
$this->assertTrue($this->request->attributes->has(ResponseListener::COOKIE_ATTR_NAME));
8484

8585
/** @var Cookie $cookie */
8686
$cookie = $this->request->attributes->get(ResponseListener::COOKIE_ATTR_NAME);
87-
$this->assertNotEquals((new RememberMeDetails(InMemoryUser::class, 'wouter', $expire, $signature))->toString(), $cookie->getValue());
87+
$this->assertNotEquals((new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', $expire, $signature))->toString(), $cookie->getValue());
8888
}
8989

9090
public function testConsumeRememberMeCookieInvalidHash()
9191
{
9292
$this->expectException(AuthenticationException::class);
9393
$this->expectExceptionMessage('The cookie\'s hash is invalid.');
94-
$this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', time() + 600, 'badsignature'));
94+
$this->handler->consumeRememberMeCookie(new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', time() + 600, 'badsignature'));
9595
}
9696

9797
public function testConsumeRememberMeCookieExpired()
@@ -101,6 +101,6 @@ public function testConsumeRememberMeCookieExpired()
101101

102102
$this->expectException(AuthenticationException::class);
103103
$this->expectExceptionMessage('The cookie has expired.');
104-
$this->handler->consumeRememberMeCookie(new RememberMeDetails(InMemoryUser::class, 'wouter', 360, $signature));
104+
$this->handler->consumeRememberMeCookie(new RememberMeDetails(RememberMeDetails::computeUserFqcnHash(InMemoryUser::class), 'wouter', 360, $signature));
105105
}
106106
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.