Summary
Hello,
I ran into https://github.com/spring-projects/spring-security/issues/8498 this week. Specifically:
- I upgraded from Spring Security 5.1.6 to 5.3.3.
- in so doing our password hashing (performed on every application endpoint request) went from fast to slow.
- because the strength-4 BCrypt hash was internally upgraded to a strength-10 one.
- none of our existing tests caught this, because our service's functionality was unaffected, only its performance.
- the impact was significant, as the endpoints we use this Basic Auth on have dozens - hundreds of requests / second.
So I would like to request that the password upgrade feature be made more configurable.
Actual Behavior
Upon encountering a BCrypt password hash of any strength smaller than 10, Spring Security will internally re-encode the plaintext matching this hash (once it is presented by a client) with a BCrypt encoder with strength 10. From that point on, all plaintext to hash comparisons will be performed at strength 10. This imposes a significant performance cost if done often.
This happens because:
- org.springframework.security.crypto.factory.PasswordEncoderFactories#createDelegatingPasswordEncoder() creates a BCryptPasswordEncoder with strength 10 (not configurable).
- org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder#upgradeEncoding returns true if the strength of the encoded password is smaller than the strength of that encoder instance, i.e. 10 (also not configurable).
I worked around this issue by defining my own DelegatingPasswordEncoder with its own custom-strength BCryptPasswordEncoder. That seems like a bit too much work for someone just wanting to use HTTP Basic Auth.
Expected Behavior
One or more of the following: - the password upgrade feature has an on/off flag. - the password encoder created by default (i.e. absent any user-defined beans) is configurable via properties. - perhaps a third option I'm not considering.
Configuration
See the attached project.
Version
Spring Security 5.3.4.RELEASE.
Sample
Attached. demo.zip
Thank you.
Comment From: mirsilstan
We had the same issue on upgrading Spring Security. In our case it was worse because previously we were using NoOpPasswordEncoder and this upgradeEncoding method switches directly to BCrypt. The CPU usage of BCrypt is very high, but this is documented, what is kind of unexpected is the switch or upgrade. Configuring the DaoAuthenticationProvider programmatically fixes the issue.
Comment From: jzheaux
Sorry that you experienced trouble with the upgrade, @andreild, this could have been messaged better.
I'm going to close this as a duplicate of https://github.com/spring-projects/spring-security/issues/5939. https://github.com/spring-projects/spring-security/issues/5939#issuecomment-428996180 contains the recommended approach for overriding the defaults.