Skip to content

Commit 13d7d3a

Browse files
committed
[Security] limited the password length passed to encoders
1 parent 2f19dab commit 13d7d3a

File tree

6 files changed

+79
-1
lines changed

6 files changed

+79
-1
lines changed

src/Symfony/Component/Security/Core/Encoder/BasePasswordEncoder.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
abstract class BasePasswordEncoder implements PasswordEncoderInterface
2020
{
21+
const MAX_PASSWORD_LENGTH = 4096;
22+
2123
/**
2224
* Demerges a merge password and salt string.
2325
*
@@ -88,4 +90,14 @@ protected function comparePasswords($password1, $password2)
8890

8991
return 0 === $result;
9092
}
93+
94+
/**
95+
* Checks if the password is too long.
96+
*
97+
* @return Boolean true if the password is too long, false otherwise
98+
*/
99+
protected function isPasswordTooLong($password)
100+
{
101+
return strlen($password) > self::MAX_PASSWORD_LENGTH;
102+
}
91103
}

src/Symfony/Component/Security/Core/Encoder/MessageDigestPasswordEncoder.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Security\Core\Encoder;
1313

14+
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
15+
1416
/**
1517
* MessageDigestPasswordEncoder uses a message digest algorithm.
1618
*
@@ -40,6 +42,10 @@ public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $
4042
*/
4143
public function encodePassword($raw, $salt)
4244
{
45+
if ($this->isPasswordTooLong($raw)) {
46+
throw new BadCredentialsException('Invalid password.');
47+
}
48+
4349
if (!in_array($this->algorithm, hash_algos(), true)) {
4450
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
4551
}
@@ -60,6 +66,6 @@ public function encodePassword($raw, $salt)
6066
*/
6167
public function isPasswordValid($encoded, $raw, $salt)
6268
{
63-
return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
69+
return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
6470
}
6571
}

src/Symfony/Component/Security/Core/Encoder/PlaintextPasswordEncoder.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Security\Core\Encoder;
1313

14+
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
15+
1416
/**
1517
* PlaintextPasswordEncoder does not do any encoding.
1618
*
@@ -30,6 +32,10 @@ public function __construct($ignorePasswordCase = false)
3032
*/
3133
public function encodePassword($raw, $salt)
3234
{
35+
if ($this->isPasswordTooLong($raw)) {
36+
throw new BadCredentialsException('Invalid password.');
37+
}
38+
3339
return $this->mergePasswordAndSalt($raw, $salt);
3440
}
3541

@@ -38,6 +44,10 @@ public function encodePassword($raw, $salt)
3844
*/
3945
public function isPasswordValid($encoded, $raw, $salt)
4046
{
47+
if ($this->isPasswordTooLong($raw)) {
48+
return false;
49+
}
50+
4151
$pass2 = $this->mergePasswordAndSalt($raw, $salt);
4252

4353
if (!$this->ignorePasswordCase) {

tests/Symfony/Tests/Component/Security/Core/Encoder/BasePasswordEncoderTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ public function testMergePasswordAndSaltWithException()
5353
$this->invokeMergePasswordAndSalt('password', '{foo}');
5454
}
5555

56+
public function testIsPasswordTooLong()
57+
{
58+
$this->assertTrue($this->invokeIsPasswordTooLong(str_repeat('a', 10000)));
59+
$this->assertFalse($this->invokeIsPasswordTooLong(str_repeat('a', 10)));
60+
}
61+
5662
protected function invokeDemergePasswordAndSalt($password)
5763
{
5864
$encoder = new PasswordEncoder();
@@ -82,4 +88,14 @@ protected function invokeComparePasswords($p1, $p2)
8288

8389
return $m->invoke($encoder, $p1, $p2);
8490
}
91+
92+
protected function invokeIsPasswordTooLong($p)
93+
{
94+
$encoder = new PasswordEncoder();
95+
$r = new \ReflectionObject($encoder);
96+
$m = $r->getMethod('isPasswordTooLong');
97+
$m->setAccessible(true);
98+
99+
return $m->invoke($encoder, $p);
100+
}
85101
}

tests/Symfony/Tests/Component/Security/Core/Encoder/MessageDigestPasswordEncoderTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,21 @@ 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+
public function testCheckPasswordLength()
57+
{
58+
$encoder = new MessageDigestPasswordEncoder();
59+
60+
$this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'));
61+
}
4562
}

tests/Symfony/Tests/Component/Security/Core/Encoder/PlaintextPasswordEncoderTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,21 @@ 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+
public function testCheckPasswordLength()
51+
{
52+
$encoder = new PlaintextPasswordEncoder();
53+
54+
$this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), 'salt'));
55+
}
3956
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy