87 lines
3.1 KiB
Plaintext
87 lines
3.1 KiB
Plaintext
include::../description.adoc[]
|
|
|
|
include::../ask-yourself.adoc[]
|
|
|
|
include::../recommended.adoc[]
|
|
|
|
== Sensitive Code Example
|
|
|
|
In a Spring-security web application the username leaks when:
|
|
|
|
* The string used as argument of https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/UserDetailsService.html[loadUserByUsername] method is used in an exception message:
|
|
|
|
----
|
|
public String authenticate(String username, String password) {
|
|
// ....
|
|
MyUserDetailsService s1 = new MyUserDetailsService();
|
|
MyUserPrincipal u1 = s1.loadUserByUsername(username);
|
|
|
|
if(u1 == null) {
|
|
throw new BadCredentialsException(username+" doesn't exist in our database"); // Sensitive
|
|
}
|
|
// ....
|
|
}
|
|
----
|
|
|
|
* https://docs.spring.io/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/core/userdetails/UsernameNotFoundException.html[UsernameNotFoundException] is thrown (except when it is in the loadUserByUsername method):
|
|
|
|
----
|
|
public String authenticate(String username, String password) {
|
|
// ....
|
|
if(user == null) {
|
|
throw new UsernameNotFoundException("user not found"); // Sensitive
|
|
}
|
|
// ....
|
|
}
|
|
----
|
|
|
|
* https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.html#setHideUserNotFoundExceptions-boolean-[HideUserNotFoundExceptions] is set to false:
|
|
|
|
----
|
|
DaoAuthenticationProvider daoauth = new DaoAuthenticationProvider();
|
|
daoauth.setUserDetailsService(new MyUserDetailsService());
|
|
daoauth.setPasswordEncoder(new BCryptPasswordEncoder());
|
|
daoauth.setHideUserNotFoundExceptions(false); // Sensitive
|
|
builder.authenticationProvider(daoauth);
|
|
----
|
|
|
|
== Compliant Solution
|
|
|
|
In a Spring-security web application:
|
|
|
|
* the same message should be used regardless of whether it is the wrong user or password:
|
|
|
|
----
|
|
public String authenticate(String username, String password) throws AuthenticationException {
|
|
Details user = null;
|
|
try {
|
|
user = loadUserByUsername(username);
|
|
} catch (UsernameNotFoundException | DataAccessException e) {
|
|
// Hide this exception reason to not disclose that the username doesn't exist
|
|
}
|
|
if (user == null || !user.isPasswordCorrect(password)) {
|
|
// User should not be able to guess if the bad credentials message is related to the username or the password
|
|
throw new BadCredentialsException("Bad credentials");
|
|
}
|
|
}
|
|
----
|
|
|
|
* https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.html#setHideUserNotFoundExceptions-boolean-[HideUserNotFoundExceptions] should be set to true:
|
|
|
|
----
|
|
DaoAuthenticationProvider daoauth = new DaoAuthenticationProvider();
|
|
daoauth.setUserDetailsService(new MyUserDetailsService());
|
|
daoauth.setPasswordEncoder(new BCryptPasswordEncoder());
|
|
daoauth.setHideUserNotFoundExceptions(true); // Compliant
|
|
builder.authenticationProvider(daoauth);
|
|
----
|
|
|
|
include::../see.adoc[]
|
|
|
|
ifdef::rspecator-view[]
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::comments-and-links.adoc[]
|
|
endif::rspecator-view[]
|