Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[security] Error when calling needsRehash() with null password #34824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
etiennerousseau opened this issue Dec 4, 2019 · 10 comments
Closed

[security] Error when calling needsRehash() with null password #34824

etiennerousseau opened this issue Dec 4, 2019 · 10 comments

Comments

@etiennerousseau
Copy link

Symfony version(s) affected: 4.4.1

Description
Using the form_login authentification provider with a database user provider, got an error when login with a user with a null password (in the entity/database) :

Argument 1 passed to Symfony\Component\Security\Core\Encoder\NativePasswordEncoder::needsRehash() must be of the type string, null given, called in ...\vendor\symfony\security-core\Encoder\MigratingPasswordEncoder.php on line 51

This works in Symfony 4.1.

How to reproduce
Create an application with

  • A User Entity
  • A form and a controller for login
  • Configure security
security:
    encoders:
        App\Entity\User:
            algorithm: 'bcrypt'
   providers:
        our_db_provider:
            entity:
                class: App\Entity\User 
   firewalls:
        main:
            anonymous: true
            form_login:
                login_path: login
                check_path: login
            provider: our_db_provider
  • Add a user with an empty password
  • Try to authenticate with this user

Possible Solution
Make parameter $encoded nullable in Symfony\Component\Security\Core\Encoder\NativePasswordEncoder::needsRehash()

Additional context
In my case I have null password because some users are authenticate with the form_login (password is in the User entity) others are authenticate with form_login_ldap (in this case the password is null in the User entity).

@xabbuh
Copy link
Member

xabbuh commented Dec 4, 2019

Can you confirm that #34802 will fix this?

@etiennerousseau
Copy link
Author

No it doesn't...

In DaoAuthenticationProvider::checkAuthentication, the call of $encoder->isPasswordValid() (line 60) leads to the error.

Here's the Stack Trace

TypeError:
Argument 1 passed to Symfony\Component\Security\Core\Encoder\NativePasswordEncoder::needsRehash() must be of the type string, null given, called in D:\erousseau\Documents\Projets Symfony\fredi\vendor\symfony\security-core\Encoder\MigratingPasswordEncoder.php on line 51

  at D:\erousseau\Documents\Projets Symfony\fredi\vendor\symfony\security-core\Encoder\NativePasswordEncoder.php:102
  at Symfony\Component\Security\Core\Encoder\NativePasswordEncoder->needsRehash(null)
     (D:\erousseau\Documents\Projets Symfony\fredi\vendor\symfony\security-core\Encoder\MigratingPasswordEncoder.php:51)
  at Symfony\Component\Security\Core\Encoder\MigratingPasswordEncoder->isPasswordValid(null, 'xxxx', null)
     (D:\erousseau\Documents\Projets Symfony\fredi\vendor\symfony\security-core\Authentication\Provider\DaoAuthenticationProvider.php:60)
  at Symfony\Component\Security\Core\Authentication\Provider\DaoAuthenticationProvider->checkAuthentication(object(User), object(UsernamePasswordToken))
     (D:\erousseau\Documents\Projets Symfony\fredi\vendor\symfony\security-core\Authentication\Provider\UserAuthenticationProvider.php:81)
...

@xabbuh
Copy link
Member

xabbuh commented Dec 4, 2019

Oh, there was also #34779. Does that help?

@etiennerousseau
Copy link
Author

No Doesn't help.

The problem occures because of the signature of the methode needsRehash(string $encoded)

Either the signature is change to needsRehash(?string $encoded), either we have to test the password before calling needsRehash($encoded) (for each encoder).

@xabbuh
Copy link
Member

xabbuh commented Dec 5, 2019

I fail to see how this could happen when both PRs are merged. We will then cover all the cases where the password is null if I don't miss anything.

@etiennerousseau
Copy link
Author

The call to needsRehash() is made in the method MigratingPasswordEncoder->isPasswordValid() (see Track Trace above).
A possible solution is to add a test before calling needsRehash() (line 51) :

final class MigratingPasswordEncoder extends BasePasswordEncoder implements SelfSaltingEncoderInterface
{
   ...
    public function isPasswordValid($encoded, $raw, $salt): bool
    {
       ...
       if (null === $encoded || !$this->bestEncoder->needsRehash($encoded)) {
            return false;
        }
        ...
    }

@chalasr
Copy link
Member

chalasr commented Dec 5, 2019

Got it, #34802 should throw before calling isPasswordValid() since it might call needsRehash() internally. Neither needsRehash nor isPasswordValid should accept null, the password encoder should just not be used at all in this case.

@etiennerousseau
Copy link
Author

Sorry but PR #34802 doesn't solves the problem.
The call to needsRehash() is made in the method MigratingPasswordEncoder->isPasswordValid() (see Track Trace above).

@chalasr
Copy link
Member

chalasr commented Dec 8, 2019

From your stack trace the call happens at DaoAuthenticationProvider.php:60 whereas it cannot be reached anymore in case of null password:

if (null === $user->getPassword()) {
throw new BadCredentialsException('The presented password is invalid.');
}
$encoder = $this->encoderFactory->getEncoder($user);
if (!$encoder->isPasswordValid($user->getPassword(), $presentedPassword, $user->getSalt())) {
throw new BadCredentialsException('The presented password is invalid.');
}

@etiennerousseau
Copy link
Author

Oh, sorry, I missed a PR...
Thank you !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants