Broken Authentication in Spring Boot with Bearer Tokens
Broken Authentication in Spring Boot with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Broken Authentication in Spring Boot when Bearer Tokens are used typically arises from misconfigurations in how tokens are generated, validated, stored, and transmitted. Spring Security’s default behavior does not automatically protect every scenario, especially when developers rely on convenience features or copy insecure examples. A common root cause is missing or weak token validation, where an endpoint accepts any string in the Authorization header without verifying its signature, issuer, audience, or expiration.
Consider a Spring Boot resource server that expects JWT Bearer Tokens but does not enforce issuer validation. An attacker can craft a valid JWT with a different issuer but the same signing algorithm and public-key infrastructure (PKI) assumptions, gaining unauthorized access. Insecure storage of secrets used to sign tokens on the server side can lead to token forgery. If the application logs Authorization headers or exposes tokens in URLs or browser history via redirects, interception risks increase. Additionally, missing HTTPS allows token sniffing in transit, and weak token revocation mechanisms enable reuse of compromised tokens.
Spring Boot applications using Spring Security’s OAuth2 Resource Server with JWT can be vulnerable when the jwt() configuration omits required validators. For example, failing to set the issuer URI or audience allows tokens issued for other services to be accepted. Similarly, not configuring a proper JwtDecoder with a strict NimbusJwtDecoder and a key locator that verifies signatures correctly can lead to acceptance of unsigned or weakly signed tokens. These gaps map to OWASP API Top 10 categories such as Broken Object Level Authorization (BOLA) and Security Misconfiguration, and may be reflected in findings from scans run with tools like middleBrick, which tests unauthenticated attack surfaces and reports related findings with remediation guidance.
Specific anti-patterns include exposing tokens in server logs, failing to set short token lifetimes, not using refresh token rotation, and neglecting to validate the aud (audience) and iss (issuer) claims. An attacker can exploit missing rate limiting on token introspection or revocation endpoints to brute-force valid tokens. MiddleBrick’s LLM/AI Security checks do not apply here, but its standard security checks—Authentication, Authorization, Input Validation, and Rate Limiting—can detect symptoms of broken authentication in runtime tests, providing prioritized findings and remediation steps.
Real-world references include CVE patterns where JWTs with none algorithm or missing signature validation were accepted, leading to account takeover. Compliance frameworks such as OWASP API Top 10, PCI-DSS, and SOC2 highlight the importance of strong authentication and token integrity. A secure Spring Boot implementation must validate tokens rigorously, enforce HTTPS, rotate keys, and monitor for anomalous token usage to mitigate Broken Authentication risks effectively.
Bearer Tokens-Specific Remediation in Spring Boot — concrete code fixes
Remediation focuses on strict token validation, secure transmission, and proper configuration of Spring Security’s resource server components. Always enforce HTTPS in production to protect tokens in transit. Configure the resource server to validate token signatures, issuer, audience, and expiration using a properly constructed JwtDecoder. Avoid accepting unsigned tokens and ensure that token revocation is supported via short-lived access tokens and secure refresh token handling.
Below are concrete, working code examples for secure Bearer Token handling in Spring Boot.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Value("${security.oauth2.resourceserver.jwt.issuer-uri}")
private String issuerUri;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authz -> authz
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
@Bean
public JwtDecoder jwtDecoder() {
NimbusJwtDecoder decoder = NimbusJwtDecoder.withIssuerLocation(issuerUri).build();
decoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(issuerUri));
return decoder;
}
}
In this configuration, the issuer URI is externalized, and the decoder validates the token’s signature and standard claims. Ensure the issuer URI points to a reliable authorization server’s well-known configuration endpoint (e.g., https://auth.example.com/.well-known/openid-configuration).
For more control, define a custom decoder with a specific public key or key set:
@Bean
public JwtDecoder jwtDecoder() {
String jwkSetUri = "https://auth.example.com/.well-known/jwks.json";
NimbusJwtDecoder decoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
decoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(
JwtValidators.createDefaultWithIssuer(issuerUri),
new AudienceValidator("my-api-audience")
));
return decoder;
}
static class AudienceValidator implements OAuth2TokenValidator {
private final String expectedAudience;
public AudienceValidator(String expectedAudience) {
this.expectedAudience = expectedAudience;
}
@Override
public OAuth2TokenValidatorResult validate(Jwt token) {
List audiences = token.getAudience();
if (audiences.contains(expectedAudience)) {
return OAuth2TokenValidatorResult.success();
}
return OAuth2TokenValidatorResult.failure(new OAuth2Error("invalid_audience"));
}
}
These examples ensure that tokens are validated for correct issuer, audience, and signature, reducing the risk of Broken Authentication. Combine this with secure storage of signing keys, short access token lifetimes, and refresh token rotation. Use tools like middleBrick’s CLI (middlebrick scan <url>) or its GitHub Action to integrate checks into CI/CD pipelines, ensuring ongoing compliance and early detection of authentication issues.
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 |