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 219118a

Browse filesBrowse files
thewilkybarkidnicolas-grekas
authored andcommitted
[Security] Fail gracefully if the security token cannot be unserialized from the session
1 parent 05adcd0 commit 219118a
Copy full SHA for 219118a

File tree

2 files changed

+34
-1
lines changed
Filter options

2 files changed

+34
-1
lines changed

‎src/Symfony/Component/Security/Http/Firewall/ContextListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Firewall/ContextListener.php
+33-1Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function handle(GetResponseEvent $event)
7777
return;
7878
}
7979

80-
$token = unserialize($token);
80+
$token = $this->safelyUnserialize($token);
8181

8282
if (null !== $this->logger) {
8383
$this->logger->debug('Read existing security token from the session.', array('key' => $this->sessionKey));
@@ -171,4 +171,36 @@ protected function refreshUser(TokenInterface $token)
171171

172172
throw new \RuntimeException(sprintf('There is no user provider for user "%s".', get_class($user)));
173173
}
174+
175+
private function safelyUnserialize($serializedToken)
176+
{
177+
$eCode = 0x37313bc;
178+
$e = $token = null;
179+
$prevUnserializeHandler = ini_set('unserialize_callback_func', '');
180+
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = array()) use (&$prevErrorHandler, $eCode) {
181+
if (E_WARNING === $type && ('Class __PHP_Incomplete_Class has no unserializer' === $msg || 0 === strpos($msg, 'unserialize(): '))) {
182+
throw new \ErrorException($msg, $eCode, $type, $file, $line);
183+
}
184+
185+
return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
186+
});
187+
188+
try {
189+
$token = unserialize($serializedToken);
190+
} catch (\Error $e) {
191+
} catch (\Exception $e) {
192+
}
193+
restore_error_handler();
194+
ini_set('unserialize_callback_func', $prevUnserializeHandler);
195+
if ($e) {
196+
if (!$e instanceof \ErrorException || $eCode !== $e->getCode()) {
197+
throw $e;
198+
}
199+
if ($logger) {
200+
$this->logger->warning('Failed to unserialize the security token from the session.', array('key' => $this->sessionKey, 'received' => $serializedToken, 'exception' => $e));
201+
}
202+
}
203+
204+
return $token;
205+
}
174206
}

‎src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Security/Http/Tests/Firewall/ContextListenerTest.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ public function testInvalidTokenInSession($token)
169169
public function provideInvalidToken()
170170
{
171171
return array(
172+
array('foo'),
172173
array(serialize(new \__PHP_Incomplete_Class())),
173174
array(serialize(null)),
174175
array(null),

0 commit comments

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