[Security] AbstractRememberMeServices::encodeCookie() validates cookie parts

This commit is contained in:
Dawid Nowak 2015-05-17 22:37:53 +02:00 committed by Fabien Potencier
parent 4d40852596
commit 464c39a77f
3 changed files with 42 additions and 4 deletions

View File

@ -268,9 +268,17 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @param array $cookieParts
*
* @return string
*
* @throws \InvalidArgumentException When $cookieParts contain the cookie delimiter. Extending class should either remove or escape it.
*/
protected function encodeCookie(array $cookieParts)
{
foreach ($cookieParts as $cookiePart) {
if (false !== strpos($cookiePart, self::COOKIE_DELIMITER)) {
throw new \InvalidArgumentException(sprintf('$cookieParts should not contain the cookie delimiter "%s"', self::COOKIE_DELIMITER));
}
}
return base64_encode(implode(self::COOKIE_DELIMITER, $cookieParts));
}

View File

@ -119,8 +119,6 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
* @param int $expires The Unix timestamp when the cookie expires
* @param string $password The encoded password
*
* @throws \RuntimeException if username contains invalid chars
*
* @return string
*/
protected function generateCookieValue($class, $username, $expires, $password)
@ -141,8 +139,6 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
* @param int $expires The Unix timestamp when the cookie expires
* @param string $password The encoded password
*
* @throws \RuntimeException when the private key is empty
*
* @return string
*/
protected function generateCookieHash($class, $username, $expires, $password)

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Tests\Http\RememberMe;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices;
class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
{
@ -236,6 +237,30 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
);
}
public function testEncodeCookieAndDecodeCookieAreInvertible()
{
$cookieParts = array('aa', 'bb', 'cc');
$service = $this->getService();
$encoded = $this->callProtected($service, 'encodeCookie', array($cookieParts));
$this->assertInternalType('string', $encoded);
$decoded = $this->callProtected($service, 'decodeCookie', array($encoded));
$this->assertSame($cookieParts, $decoded);
}
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage cookie delimiter
*/
public function testThereShouldBeNoCookieDelimiterInCookieParts()
{
$cookieParts = array('aa', 'b'.AbstractRememberMeServices::COOKIE_DELIMITER.'b', 'cc');
$service = $this->getService();
$this->callProtected($service, 'encodeCookie', array($cookieParts));
}
protected function getService($userProvider = null, $options = array(), $logger = null)
{
if (null === $userProvider) {
@ -258,4 +283,13 @@ class AbstractRememberMeServicesTest extends \PHPUnit_Framework_TestCase
return $provider;
}
private function callProtected($object, $method, array $args)
{
$reflection = new \ReflectionClass(get_class($object));
$reflectionMethod = $reflection->getMethod($method);
$reflectionMethod->setAccessible(true);
return $reflectionMethod->invokeArgs($object, $args);
}
}