diff options
author | Fabien Potencier <fabien.potencier@gmail.com> | 2013-10-10 15:12:30 +0200 |
---|---|---|
committer | Fabien Potencier <fabien.potencier@gmail.com> | 2013-10-10 15:12:30 +0200 |
commit | b6d302f1f0f1235aa376c180dcd289f38b3df70e (patch) | |
tree | 676aa0d8ce931531f31494da3f65a2d8f12bb967 | |
parent | 5d889265454c4b094e894a14f0d9b4687fa644e1 (diff) | |
parent | 41cbe3694a5332d7e5bdb285c81bbfe23f31a220 (diff) | |
download | symfony-security-b6d302f1f0f1235aa376c180dcd289f38b3df70e.zip symfony-security-b6d302f1f0f1235aa376c180dcd289f38b3df70e.tar.gz symfony-security-b6d302f1f0f1235aa376c180dcd289f38b3df70e.tar.bz2 |
Merge branch '2.2' into 2.3v2.3.6
* 2.2:
bumped Symfony version to 2.2.10
updated VERSION for 2.2.9
update CONTRIBUTORS for 2.2.9
updated CHANGELOG for 2.2.9
[Security] limited the password length passed to encoders
assets:install command should mirror .dotfiles (.htaccess)
PoFileDumper - PO headers
removed whitespaces
Conflicts:
src/Symfony/Component/HttpKernel/Kernel.php
src/Symfony/Component/Security/Core/Encoder/BCryptPasswordEncoder.php
-rw-r--r-- | Core/Encoder/BCryptPasswordEncoder.php | 7 | ||||
-rw-r--r-- | Core/Encoder/BasePasswordEncoder.php | 12 | ||||
-rw-r--r-- | Core/Encoder/MessageDigestPasswordEncoder.php | 8 | ||||
-rw-r--r-- | Core/Encoder/Pbkdf2PasswordEncoder.php | 8 | ||||
-rw-r--r-- | Core/Encoder/PlaintextPasswordEncoder.php | 10 | ||||
-rw-r--r-- | Tests/Core/Encoder/BCryptPasswordEncoderTest.php | 17 | ||||
-rw-r--r-- | Tests/Core/Encoder/BasePasswordEncoderTest.php | 16 | ||||
-rw-r--r-- | Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php | 17 | ||||
-rw-r--r-- | Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php | 17 | ||||
-rw-r--r-- | Tests/Core/Encoder/PlaintextPasswordEncoderTest.php | 17 |
10 files changed, 126 insertions, 3 deletions
diff --git a/Core/Encoder/BCryptPasswordEncoder.php b/Core/Encoder/BCryptPasswordEncoder.php index 9349291..fc79021 100644 --- a/Core/Encoder/BCryptPasswordEncoder.php +++ b/Core/Encoder/BCryptPasswordEncoder.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Core\Encoder; use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; /** * @author Elnur Abdurrakhimov <elnur@elnur.pro> @@ -64,6 +65,10 @@ class BCryptPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + $options = array('cost' => $this->cost); if ($salt) { @@ -78,6 +83,6 @@ class BCryptPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { - return password_verify($raw, $encoded); + return !$this->isPasswordTooLong($raw) && password_verify($raw, $encoded); } } diff --git a/Core/Encoder/BasePasswordEncoder.php b/Core/Encoder/BasePasswordEncoder.php index c26c9ce..b83eb30 100644 --- a/Core/Encoder/BasePasswordEncoder.php +++ b/Core/Encoder/BasePasswordEncoder.php @@ -20,6 +20,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 +85,14 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface { return StringUtils::equals($password1, $password2); } + + /** + * Checks if the password is too long. + * + * @return Boolean true if the password is too long, false otherwise + */ + protected function isPasswordTooLong($password) + { + return strlen($password) > self::MAX_PASSWORD_LENGTH; + } } diff --git a/Core/Encoder/MessageDigestPasswordEncoder.php b/Core/Encoder/MessageDigestPasswordEncoder.php index a8bd553..a7e5546 100644 --- a/Core/Encoder/MessageDigestPasswordEncoder.php +++ b/Core/Encoder/MessageDigestPasswordEncoder.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Security\Core\Encoder; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; + /** * MessageDigestPasswordEncoder uses a message digest algorithm. * @@ -41,6 +43,10 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + if (!in_array($this->algorithm, hash_algos(), true)) { throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); } @@ -61,6 +67,6 @@ class MessageDigestPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { - return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); + return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); } } diff --git a/Core/Encoder/Pbkdf2PasswordEncoder.php b/Core/Encoder/Pbkdf2PasswordEncoder.php index 4f37ba3..8a5a958 100644 --- a/Core/Encoder/Pbkdf2PasswordEncoder.php +++ b/Core/Encoder/Pbkdf2PasswordEncoder.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Security\Core\Encoder; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; + /** * Pbkdf2PasswordEncoder uses the PBKDF2 (Password-Based Key Derivation Function 2). * @@ -54,6 +56,10 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + if (!in_array($this->algorithm, hash_algos(), true)) { throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm)); } @@ -72,7 +78,7 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { - return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); + return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt)); } private function hashPbkdf2($algorithm, $password, $salt, $iterations, $length = 0) diff --git a/Core/Encoder/PlaintextPasswordEncoder.php b/Core/Encoder/PlaintextPasswordEncoder.php index c21f3cd..22f3da4 100644 --- a/Core/Encoder/PlaintextPasswordEncoder.php +++ b/Core/Encoder/PlaintextPasswordEncoder.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Security\Core\Encoder; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; + /** * PlaintextPasswordEncoder does not do any encoding. * @@ -35,6 +37,10 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + throw new BadCredentialsException('Invalid password.'); + } + return $this->mergePasswordAndSalt($raw, $salt); } @@ -43,6 +49,10 @@ class PlaintextPasswordEncoder extends BasePasswordEncoder */ public function isPasswordValid($encoded, $raw, $salt) { + if ($this->isPasswordTooLong($raw)) { + return false; + } + $pass2 = $this->mergePasswordAndSalt($raw, $salt); if (!$this->ignorePasswordCase) { diff --git a/Tests/Core/Encoder/BCryptPasswordEncoderTest.php b/Tests/Core/Encoder/BCryptPasswordEncoderTest.php index 49c1051..dd962fd 100644 --- a/Tests/Core/Encoder/BCryptPasswordEncoderTest.php +++ b/Tests/Core/Encoder/BCryptPasswordEncoderTest.php @@ -70,4 +70,21 @@ class BCryptPasswordEncoderTest extends \PHPUnit_Framework_TestCase $this->markTestSkipped('Requires PHP >= 5.3.7'); } } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + */ + public function testEncodePasswordLength() + { + $encoder = new BCryptPasswordEncoder(self::VALID_COST); + + $encoder->encodePassword(str_repeat('a', 5000), 'salt'); + } + + public function testCheckPasswordLength() + { + $encoder = new BCryptPasswordEncoder(self::VALID_COST); + + $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt')); + } } diff --git a/Tests/Core/Encoder/BasePasswordEncoderTest.php b/Tests/Core/Encoder/BasePasswordEncoderTest.php index 2ef1dcc..762f6ab 100644 --- a/Tests/Core/Encoder/BasePasswordEncoderTest.php +++ b/Tests/Core/Encoder/BasePasswordEncoderTest.php @@ -53,6 +53,12 @@ class BasePasswordEncoderTest extends \PHPUnit_Framework_TestCase $this->invokeMergePasswordAndSalt('password', '{foo}'); } + public function testIsPasswordTooLong() + { + $this->assertTrue($this->invokeIsPasswordTooLong(str_repeat('a', 10000))); + $this->assertFalse($this->invokeIsPasswordTooLong(str_repeat('a', 10))); + } + protected function invokeDemergePasswordAndSalt($password) { $encoder = new PasswordEncoder(); @@ -82,4 +88,14 @@ class BasePasswordEncoderTest extends \PHPUnit_Framework_TestCase return $m->invoke($encoder, $p1, $p2); } + + protected function invokeIsPasswordTooLong($p) + { + $encoder = new PasswordEncoder(); + $r = new \ReflectionObject($encoder); + $m = $r->getMethod('isPasswordTooLong'); + $m->setAccessible(true); + + return $m->invoke($encoder, $p); + } } diff --git a/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php b/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php index 64032c4..117b8ba 100644 --- a/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php +++ b/Tests/Core/Encoder/MessageDigestPasswordEncoderTest.php @@ -42,4 +42,21 @@ 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'); + } + + public function testCheckPasswordLength() + { + $encoder = new MessageDigestPasswordEncoder(); + + $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt')); + } } diff --git a/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php b/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php index 2c98543..e303708 100644 --- a/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php +++ b/Tests/Core/Encoder/Pbkdf2PasswordEncoderTest.php @@ -42,4 +42,21 @@ 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('foobar'); + + $encoder->encodePassword(str_repeat('a', 5000), 'salt'); + } + + public function testCheckPasswordLength() + { + $encoder = new Pbkdf2PasswordEncoder('foobar'); + + $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt')); + } } diff --git a/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php b/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php index af0008f..8b1b888 100644 --- a/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php +++ b/Tests/Core/Encoder/PlaintextPasswordEncoderTest.php @@ -36,4 +36,21 @@ 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'); + } + + public function testCheckPasswordLength() + { + $encoder = new PlaintextPasswordEncoder(); + + $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt')); + } } |