Skip to content

Commit c6ff85e

Browse files
committed
[Security] limited the password length passed to encoders
1 parent 019e74e commit c6ff85e

9 files changed

+106
-0
lines changed

Encoder/BCryptPasswordEncoder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public function __construct($cost)
6464
*/
6565
public function encodePassword($raw, $salt)
6666
{
67+
$this->checkPasswordLength($raw);
68+
6769
$options = array('cost' => $this->cost);
6870

6971
if ($salt) {
@@ -78,6 +80,8 @@ public function encodePassword($raw, $salt)
7880
*/
7981
public function isPasswordValid($encoded, $raw, $salt)
8082
{
83+
$this->checkPasswordLength($raw);
84+
8185
return password_verify($raw, $encoded);
8286
}
8387
}

Encoder/BasePasswordEncoder.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Security\Core\Encoder;
1313

1414
use Symfony\Component\Security\Core\Util\StringUtils;
15+
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
1516

1617
/**
1718
* BasePasswordEncoder is the base class for all password encoders.
@@ -20,6 +21,8 @@
2021
*/
2122
abstract class BasePasswordEncoder implements PasswordEncoderInterface
2223
{
24+
const MAX_PASSWORD_LENGTH = 4096;
25+
2326
/**
2427
* Demerges a merge password and salt string.
2528
*
@@ -83,4 +86,11 @@ protected function comparePasswords($password1, $password2)
8386
{
8487
return StringUtils::equals($password1, $password2);
8588
}
89+
90+
protected function checkPasswordLength($password)
91+
{
92+
if (strlen($password) > self::MAX_PASSWORD_LENGTH) {
93+
throw new BadCredentialsException('Invalid password.');
94+
}
95+
}
8696
}

Encoder/MessageDigestPasswordEncoder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $
4141
*/
4242
public function encodePassword($raw, $salt)
4343
{
44+
$this->checkPasswordLength($raw);
45+
4446
if (!in_array($this->algorithm, hash_algos(), true)) {
4547
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
4648
}
@@ -61,6 +63,8 @@ public function encodePassword($raw, $salt)
6163
*/
6264
public function isPasswordValid($encoded, $raw, $salt)
6365
{
66+
$this->checkPasswordLength($raw);
67+
6468
return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
6569
}
6670
}

Encoder/Pbkdf2PasswordEncoder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $
5454
*/
5555
public function encodePassword($raw, $salt)
5656
{
57+
$this->checkPasswordLength($raw);
58+
5759
if (!in_array($this->algorithm, hash_algos(), true)) {
5860
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
5961
}
@@ -72,6 +74,8 @@ public function encodePassword($raw, $salt)
7274
*/
7375
public function isPasswordValid($encoded, $raw, $salt)
7476
{
77+
$this->checkPasswordLength($raw);
78+
7579
return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
7680
}
7781

Encoder/PlaintextPasswordEncoder.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public function __construct($ignorePasswordCase = false)
3535
*/
3636
public function encodePassword($raw, $salt)
3737
{
38+
$this->checkPasswordLength($raw);
39+
3840
return $this->mergePasswordAndSalt($raw, $salt);
3941
}
4042

@@ -43,6 +45,8 @@ public function encodePassword($raw, $salt)
4345
*/
4446
public function isPasswordValid($encoded, $raw, $salt)
4547
{
48+
$this->checkPasswordLength($raw);
49+
4650
$pass2 = $this->mergePasswordAndSalt($raw, $salt);
4751

4852
if (!$this->ignorePasswordCase) {

Tests/Encoder/BCryptPasswordEncoderTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,26 @@ public function testValidation()
6464
$this->assertFalse($encoder->isPasswordValid($result, 'anotherPassword', null));
6565
}
6666

67+
/**
68+
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
69+
*/
70+
public function testEncodePasswordLength()
71+
{
72+
$encoder = new BCryptPasswordEncoder(4);
73+
74+
$encoder->encodePassword(str_repeat('a', 5000), 'salt');
75+
}
76+
77+
/**
78+
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
79+
*/
80+
public function testCheckPasswordLength()
81+
{
82+
$encoder = new BCryptPasswordEncoder(4);
83+
84+
$encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt');
85+
}
86+
6787
private function skipIfPhpVersionIsNotSupported()
6888
{
6989
if (version_compare(phpversion(), '5.3.7', '<')) {

Tests/Encoder/MessageDigestPasswordEncoderTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,24 @@ public function testEncodePasswordAlgorithmDoesNotExist()
4242
$encoder = new MessageDigestPasswordEncoder('foobar');
4343
$encoder->encodePassword('password', '');
4444
}
45+
46+
/**
47+
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
48+
*/
49+
public function testEncodePasswordLength()
50+
{
51+
$encoder = new MessageDigestPasswordEncoder();
52+
53+
$encoder->encodePassword(str_repeat('a', 5000), 'salt');
54+
}
55+
56+
/**
57+
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
58+
*/
59+
public function testCheckPasswordLength()
60+
{
61+
$encoder = new MessageDigestPasswordEncoder();
62+
63+
$encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt');
64+
}
4565
}

Tests/Encoder/Pbkdf2PasswordEncoderTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,24 @@ public function testEncodePasswordAlgorithmDoesNotExist()
4242
$encoder = new Pbkdf2PasswordEncoder('foobar');
4343
$encoder->encodePassword('password', '');
4444
}
45+
46+
/**
47+
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
48+
*/
49+
public function testEncodePasswordLength()
50+
{
51+
$encoder = new Pbkdf2PasswordEncoder();
52+
53+
$encoder->encodePassword(str_repeat('a', 5000), 'salt');
54+
}
55+
56+
/**
57+
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
58+
*/
59+
public function testCheckPasswordLength()
60+
{
61+
$encoder = new Pbkdf2PasswordEncoder();
62+
63+
$encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt');
64+
}
4565
}

Tests/Encoder/PlaintextPasswordEncoderTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,24 @@ public function testEncodePassword()
3636

3737
$this->assertSame('foo', $encoder->encodePassword('foo', ''));
3838
}
39+
40+
/**
41+
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
42+
*/
43+
public function testEncodePasswordLength()
44+
{
45+
$encoder = new PlaintextPasswordEncoder();
46+
47+
$encoder->encodePassword(str_repeat('a', 5000), 'salt');
48+
}
49+
50+
/**
51+
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
52+
*/
53+
public function testCheckPasswordLength()
54+
{
55+
$encoder = new PlaintextPasswordEncoder();
56+
57+
$encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt');
58+
}
3959
}

0 commit comments

Comments
 (0)