Maks3w / FR3DLdapBundle

This bundle integrates LDAP Authentication with any user manager (Ex: FOSUserBundle)
119 stars 77 forks source link

v2.0 -> v3.0: handling of empty passwords has changed? #162

Open engagit opened 5 years ago

engagit commented 5 years ago

Did something change between v2.0 and v3.0 that handled the situation where a user entered a blank password?

In version 2.0, if a user submitted an empty password, I would get the following in my logs:

security.INFO: Authentication request failed. {
"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException(code: 0): Bad credentials. 
at /var/www/html/vayu/backend/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php:88, 
Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException(code: 0): The presented password is invalid. at 
/var/www/html/vayu/backend/vendor/symfony/symfony/src/Symfony/Component/Security/Core/Authentication/Provider/DaoAuthenticationProvider.php:65)"} []

However, in version 3.0, this error is not thrown, and instead the bind is attempted, which results in an anonymous bind happening.

When I look at the code in your bundle, I don't see any obvious changes that would allow this to occur.

If you can tell me whether something has changed that would cause the above behavior, that would help.

Or, if nothing has changed, any hints as to where I might look is appreciated.

Thank you so much.

engagit commented 5 years ago

I should note that this is not happening on every login attempt without a password. It only occurs when a user logs in successfully with their username and password, then logs out, and then attempts to login again, but this time with no password.

This leads me to believe that perhaps the issue is actually that the same connection used for the first successful bind attempt is somehow still open when they logout and attempt to login again, which switches it to an anonymous bind, and allows no password.

Any thoughts or hints on what direction to go are appreciated.

There have been no other code changes, no relevant configuration changes, and no updates to other bundles that I haven't tested and ruled out.

lhardie commented 5 years ago

This is my personal account (I am engagit), and I have done some further testing that has me very concerned. There is a large security hole present in my application, and it appears that it may be coming from your bundle.

If a user logs into the application successfully, then logs out, the very next login attempt does not require a password, and you can enter ANY username and you will be successfully authenticated as that user.

I have tested, and I can login successfully and log out in one browser, open a new browser and enter a username with no password, and I am successfully authenticated and allowed into the application. This adds the following line to the logs: ldap_driver.DEBUG: ldap_bind(usernamehere, ****) {"action":"ldap_bind","bind_rdn":"usernamehere"} [], where I believe I should be seeing an authentication error.

Please note that I was not seeing this issue with the same configuration and the same application code with Symfony version 2.8 and FR3D Ldap Bundle version 2.0.0. On upgrading to Symfony version 3.4 and FR3D Ldap Bundle version 3.0.0, suddenly this error shows up.

I have pulled apart my code and carefully tested all other configuration changes and bundle updates to be sure it isn't something else that was updated at the same time, and have found nothing that affects this. All testing has been done on the same server with the same packages installed.

Any help is appreciated.

lhardie commented 5 years ago

Before anyone puts a bunch of time into this, I am attempting to reproduce this with a build of Symfony Standard from scratch, and so far cannot replicate. I will comment here again if I find something relevant relating to this bundle.

lhardie commented 5 years ago

So far I have been unable to reproduce this a new installation of Symfony. While this seems to point to my app code being the culprit, I made no code changes whatsoever to the authentication/login/user/etc system prior to the upgrade.

Does anyone know of something that changed from version 2.0.0 to 3.0.0 that would cause the prior authentication to be cached or saved in some manner?

Or did something change from version 2.0.0 that does a check for empty passwords to prevent an anonymous bind?

Any ideas are appreciated. In the meantime, I will take this to StackOverflow.

lhardie commented 5 years ago

I found it.

Before upgrading Symfony and the FR3D Ldap Bundle, we were using FR3D v2.0.0-ALPHA2.

In that version the LDAP Authentication Provider checks for an empty password with the following code:

if (!$presentedPassword = $token->getCredentials()) {
    throw new BadCredentialsException('The presented password cannot be empty.');
}

This would catch the case where the submitted password didn't even exist (no password parameter sent from the backend).

However, in v3.0.0, the code to check for an empty password looks like this:

if ('' === $presentedPassword) {
    throw new BadCredentialsException('The presented password cannot be empty.');
}

This entirely misses the case that the password was not even sent by the frontend. It allows someone to submit just a username, which in turn sends a request for an ldap bind that is ultimately successful if ldap allows an anonymous bind.

This is a pretty big security hole when attempting to check if a user is authenticated by performing a bind with a username and password.

Please let me know if I need to re-open and submit this as an actual bug report, or if you need more information from me.