Broken Authentication in Spring Boot with Mongodb
Broken Authentication in Spring Boot with Mongodb — how this specific combination creates or exposes the vulnerability
Broken Authentication in a Spring Boot application using Mongodb often arises from a mismatch between session/password handling in Spring Security and the way identity data is stored and retrieved from Mongodb. Common root causes include missing or weak password encoding, improper session fixation defenses, and misconfigured CORS or authentication filters that allow unauthorized access to authentication endpoints.
When user credentials are stored in Mongodb without strong, adaptive hashing (for example, using plain text or a fast hash like MD5 or SHA1), attackers who gain read access to the database can trivially recover passwords. Spring Security’s default authentication flow relies on a UserDetailsService that loads a user by a unique key (commonly the email). If the query to Mongodb does not enforce strict equality checks or uses case-insensitive collation without normalization, it can enable username enumeration or bypass intended uniqueness constraints.
Session management is another critical area. If Spring Security is configured to use stateless JWT authentication but the tokens are not properly validated on each request (e.g., missing signature verification or short expiration), an attacker can reuse captured tokens. Additionally, if Mongodb is used as a session store without proper TTL indexes or secure connection configurations, session identifiers can leak or persist beyond intended lifetimes, enabling session hijacking.
Misconfigured CORS in Spring Boot can also expose authentication endpoints to unauthorized origins, allowing malicious sites to trigger authentication requests and harvest tokens via cross-site request forgery or leakage in browser histories. Insufficient rate limiting on login endpoints stored behind a standard Mongodb deployment without additional network-level protections enables credential stuffing and brute-force attacks. Together, these factors make the Spring Boot + Mongodb stack vulnerable when authentication controls are not explicitly hardened at the framework, data, and transport layers.
Mongodb-Specific Remediation in Spring Boot — concrete code fixes
To remediate Broken Authentication when using Spring Boot with Mongodb, apply defense-in-depth measures across credential storage, session handling, and request validation. The following examples demonstrate secure configurations and code patterns.
1. Secure password storage with BCrypt
Always encode passwords using an adaptive hashing function before persisting them to Mongodb. Use BCryptPasswordEncoder and store only the hash.
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
When saving a user, encode the password before writing to Mongodb via Spring Data Mongodb:
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
public User createUser(String email, String rawPassword) {
User user = new User();
user.setEmail(email);
user.setPassword(passwordEncoder.encode(rawPassword));
return userRepository.save(user);
}
}
2. Robust UserDetailsService with strict query constraints
Implement UserDetailsService to load users by normalized email and enforce case-insensitive uniqueness at the application level, even if Mongodb collation is case-insensitive.
@Service
public class CustomUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return userRepository.findByEmailIgnoreCase(email)
.map(this::mapToUserDetails)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
}
private UserDetails mapToUserDetails(User user) {
return User.builder()
.username(user.getEmail())
.password(user.getPassword())
.roles(user.getRoles().toArray(new String[0]))
.build();
}
}
3. JWT validation and secure session handling
If using JWT, validate the signature and claims on every request. Configure Spring Security to reject unsigned tokens and enforce short expiration times.
@Configuration
@EnableWebSecurity
public class ApiSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, JwtDecoder jwtDecoder) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests(auth -> auth
.requestMatchers("/auth/login").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
@Bean
public JwtDecoder jwtDecoder() {
return SecretKeyJwtDecoder.withSecretKey("your-256-bit-secret".getBytes()).build();
}
}
4. CORS and rate limiting
Restrict CORS to known origins and enable rate limiting on authentication endpoints to mitigate brute-force attacks.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |