Skip to content
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

SEC-2056: CVE-2012-5055 DaoAuthenticationProvider can reveal which usernames are valid #2280

Closed
spring-projects-issues opened this issue Sep 19, 2012 · 3 comments
Assignees
Labels
in: web An issue in web modules (web, webmvc) type: bug A general bug type: jira An issue that was migrated from JIRA
Milestone

Comments

@spring-projects-issues
Copy link

Rob Winch (Migrated from SEC-2056) said:

Description:

Spring Security's DaoAuthenticationProvider authenticates users by utilizing the PasswordEncoder interface to compare the submitted password with the actual password. If a user is not found, the comparison is skipped which, depending on the PasswordEncoder implementation, can result in a significant difference in the amount of time required to attempt to authenticate an actual user versus a user that does not exist. This opens up the possibility of a side channel attack that would enable a malicious user to determine if a username is valid.

Example:

The DaoAuthenticationProvider allows setting of the PasswordEncoder for password validation:

DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(new BCryptPasswordEncoder());

// Authentication or failure to authenticate an actual user takes ~84ms
Authentication existingUser = new UsernamePasswordAuthenticationToken("existingUser", "password");
provider.authentication(existingUser);

// Failure to authenticate a user that does not exist takes ~0ms
Authentication missingUser = new UsernamePasswordAuthenticationToken("missingUser", "password");
provider.authentication(missingUser);

The difference between the amount of time it takes to authenticate an existing user and a user that does not exist can reveal if a username is valid or not.

Mitigation:

Applications which use DaoAuthenticationProvider and a PasswordEncoder other than PlainTextEncoder are likely to be vulnerable.

All users may mitigate this issue by upgrading to Spring Security 3.1.3+, 3.0.8+, or 2.0.8+.

Fix:

DaoAuthenticationProvider now performs PasswordEncoder.isPasswordValid when a user is not found.

Credit:

The issue was discovered by Nicholas Goodwin.

@platinumvoid
Copy link

platinumvoid commented Jul 12, 2020

Is it possible to achieve the same effect by just using a random time sleep (70-100) Thread.sleep(((long) (Math.random()*(30))) + 70);?

@jzheaux
Copy link
Contributor

jzheaux commented Jul 31, 2020

The problem with adding random sleeps is that an attacker can at the same time overtax the system to create greater disparity between the two request types. Under normal circumstances, say, both the password hash and the random sleep increase the request time by n cycles. But, while the system is taxed, password hashing may take 10n cycles while the random sleep will still take n cycles.

The best solution is for each path to do the same work - if a password is provided, then hash it, even when the username is invalid.

@rwinch
Copy link
Member

rwinch commented Aug 4, 2020

Random sleep can be normalized out. As Josh mentioned constant time is the way to avoid timing attacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web An issue in web modules (web, webmvc) type: bug A general bug type: jira An issue that was migrated from JIRA
Projects
None yet
Development

No branches or pull requests

4 participants