diff --git a/src/Symfony/Component/Security/Core/Encoder/BCryptPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/BCryptPasswordEncoder.php index a355421580..f96bb4fdf9 100644 --- a/src/Symfony/Component/Security/Core/Encoder/BCryptPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/BCryptPasswordEncoder.php @@ -64,6 +64,8 @@ class BCryptPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + $this->checkPasswordLength($raw); + $options = array('cost' => $this->cost); if ($salt) { @@ -78,6 +80,8 @@ class BCryptPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { + $this->checkPasswordLength($raw); + return password_verify($raw, $encoded); } } diff --git a/src/Symfony/Component/Security/Core/Encoder/BasePasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/BasePasswordEncoder.php index c26c9ce5fc..b7e52bb8cf 100644 --- a/src/Symfony/Component/Security/Core/Encoder/BasePasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/BasePasswordEncoder.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Core\Encoder; use Symfony\Component\Security\Core\Util\StringUtils; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; /** * BasePasswordEncoder is the base class for all password encoders. @@ -20,6 +21,8 @@ use Symfony\Component\Security\Core\Util\StringUtils; */ abstract class BasePasswordEncoder implements PasswordEncoderInterface { + const MAX_PASSWORD_LENGTH = 4096; + /** * Demerges a merge password and salt string. * @@ -83,4 +86,11 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface { return StringUtils::equals($password1, $password2); } + + protected function checkPasswordLength($password) + { + if (strlen($password) > self::MAX_PASSWORD_LENGTH) { + throw new BadCredentialsException('Invalid password.'); + } + } } diff --git a/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php index a8bd553f78..efe1e5cd75 100644 --- a/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php @@ -41,6 +41,8 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + $this->checkPasswordLength($raw); + if (!in_array($this->algorithm, hash_algos(), true)) { throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); } @@ -61,6 +63,8 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { + $this->checkPasswordLength($raw); + return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); } } diff --git a/src/Symfony/Component/Security/Core/Encoder/Pbkdf2PasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/Pbkdf2PasswordEncoder.php index 4f37ba3109..a4b5c3b6ce 100644 --- a/src/Symfony/Component/Security/Core/Encoder/Pbkdf2PasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/Pbkdf2PasswordEncoder.php @@ -54,6 +54,8 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + $this->checkPasswordLength($raw); + if (!in_array($this->algorithm, hash_algos(), true)) { throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); } @@ -72,6 +74,8 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { + $this->checkPasswordLength($raw); + return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); } diff --git a/src/Symfony/Component/Security/Core/Encoder/PlaintextPasswordEncoder.php b/src/Symfony/Component/Security/Core/Encoder/PlaintextPasswordEncoder.php index c21f3cd3f9..55aad188b5 100644 --- a/src/Symfony/Component/Security/Core/Encoder/PlaintextPasswordEncoder.php +++ b/src/Symfony/Component/Security/Core/Encoder/PlaintextPasswordEncoder.php @@ -35,6 +35,8 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + $this->checkPasswordLength($raw); + return $this->mergePasswordAndSalt($raw, $salt); } @@ -43,6 +45,8 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { + $this->checkPasswordLength($raw); + $pass2 = $this->mergePasswordAndSalt($raw, $salt); if (!$this->ignorePasswordCase) { diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/BCryptPasswordEncoderTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/BCryptPasswordEncoderTest.php index 4780411071..99f03a3cbd 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/BCryptPasswordEncoderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/BCryptPasswordEncoderTest.php @@ -64,6 +64,26 @@ class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase $this->assertFalse($encoder->isPasswordValid($result, 'anotherPassword', null)); } + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testEncodePasswordLength() + { + $encoder = new BCryptPasswordEncoder(4); + + $encoder->encodePassword(str_repeat('a', 5000), 'salt'); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testCheckPasswordLength() + { + $encoder = new BCryptPasswordEncoder(4); + + $encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'); + } + private function skipIfPhpVersionIsNotSupported() { if (version_compare(phpversion(), '5.3.7', '<')) { diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php index 550d08e484..1e8faafb3b 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/MessageDigestPasswordEncoderTest.php @@ -42,4 +42,24 @@ class MessageDigestPasswordEncoderTest extends \PHPUnit_Framework_TestCase $encoder = new MessageDigestPasswordEncoder('foobar'); $encoder->encodePassword('password', ''); } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testEncodePasswordLength() + { + $encoder = new MessageDigestPasswordEncoder(); + + $encoder->encodePassword(str_repeat('a', 5000), 'salt'); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testCheckPasswordLength() + { + $encoder = new MessageDigestPasswordEncoder(); + + $encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'); + } } diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php index ba5c4d589e..4991330931 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/Pbkdf2PasswordEncoderTest.php @@ -42,4 +42,24 @@ class Pbkdf2PasswordEncoderTest extends \PHPUnit_Framework_TestCase $encoder = new Pbkdf2PasswordEncoder('foobar'); $encoder->encodePassword('password', ''); } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testEncodePasswordLength() + { + $encoder = new Pbkdf2PasswordEncoder(); + + $encoder->encodePassword(str_repeat('a', 5000), 'salt'); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testCheckPasswordLength() + { + $encoder = new Pbkdf2PasswordEncoder(); + + $encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'); + } } diff --git a/src/Symfony/Component/Security/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php b/src/Symfony/Component/Security/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php index 513a94a75d..763aae1035 100644 --- a/src/Symfony/Component/Security/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Encoder/PlaintextPasswordEncoderTest.php @@ -36,4 +36,24 @@ class PlaintextPasswordEncoderTest extends \PHPUnit_Framework_TestCase $this->assertSame('foo', $encoder->encodePassword('foo', '')); } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testEncodePasswordLength() + { + $encoder = new PlaintextPasswordEncoder(); + + $encoder->encodePassword(str_repeat('a', 5000), 'salt'); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testCheckPasswordLength() + { + $encoder = new PlaintextPasswordEncoder(); + + $encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'); + } }