This Spring security configuration appears to store passwords in plaintext or hashed with a weak hashing algorithm. This could allow an attacker to easily steal user login information.
Configure Spring to store passwords securely.
Spring allows for great flexibility when configuring how user information is stored in the database.
User passwords in particular are a liability when not stored properly; they must be hashed and salted before storage.
Ideally, a strong hash algorithm is: * Not vulnerable to brute force attacks * Not vulnerable to collision attacks * Not vulnerable to rainbow table attacks; this is achieved by salting the password with random data.
This issue is raised when either no password encoder, or one of the following weak/deprecated password encoders is used:
StandardPasswordEncoder
- Though it claims to be standard, even Spring has deprecated its use.NoOpPasswordEncoder
- Using this is the same as not using a password encoder. While it is permissible for testing purposes, it must never be used in production.MessageDigestPasswordEncoder
- This encoder is insecure, as one could couple it with an insecure message digest algorithm.Md4PasswordEncoder
- MD4's security as a hash function is severely compromised.LdapShaPasswordEncoder
- This encoder is insecure for a number of reasons.@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("SELECT * FROM users WHERE username = ?")
.passwordEncoder(new StandardPasswordEncoder()); // StandardPasswordEncoder is not secure.
// OR
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("SELECT * FROM users WHERE username = ?"); // If no encoder is used, the password is stored as plain-text.
// OR
auth.userDetailsService(...); // Again, the password is stored as plain-text.
// OR
auth.userDetailsService(...).passwordEncoder(new LdapShaPasswordEncoder()); // Insecure.
}
Use DelegatingPassswordEncoder
with any of these encoders:
Argon2PasswordEncoder
BCryptPasswordEncoder
Pbkdf2PasswordEncoder
SCryptPasswordEncoder
- While Scrypt is quite secure, there are some concerns regarding its use with passwords.Here's an example using BCryptPasswordEncoder
:
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("Select * from users where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}