Credential Stuffing in Spring Boot with Hmac Signatures
Credential Stuffing in Spring Boot with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Credential stuffing is an automated brute-force technique that relies on lists of known username and password pairs to gain unauthorized access. When a Spring Boot API uses Hmac Signatures for request authentication but does not adequately protect the login or token validation flow, attackers can exploit the design to amplify credential stuffing campaigns.
In a typical setup, a client computes an Hmac signature over selected request parameters, a timestamp, and a secret key, then sends the signature in a header. If the server validates the signature only after minimal checks, an attacker can make many rapid requests with different credentials without triggering protections. This is especially risky when rate limiting is absent or applied after authentication logic, allowing attackers to iterate over thousands of credential pairs within seconds.
Spring Boot applications that accept JSON payloads via HTTP POST for login are common targets. Attackers replay requests with varied credentials while keeping the Hmac construction valid for each attempt, provided they can guess or obtain a per-user secret or derive it from a known credential pattern. If nonces or timestamps are not enforced strictly or are reused, signatures remain verifiable across requests, enabling automation at scale.
The lack of binding between the authenticated user context and the Hmac scope can turn a seemingly integrity-protecting mechanism into an enabler for credential stuffing. For example, if the signature covers the username and password but the server does not enforce strict lockout or progressive delays after failures, attackers can iterate rapidly. Additionally, if the API exposes timing differences in signature validation, side channels may further aid attackers in narrowing valid credentials.
middleBrick detects such patterns during black-box scanning by analyzing authentication behavior, rate limiting, and input validation across the unauthenticated attack surface. The tool flags weak binding between signature validation and anti-automation controls, providing prioritized findings with severity ratings and remediation guidance.
Hmac Signatures-Specific Remediation in Spring Boot — concrete code fixes
To mitigate credential stuffing when using Hmac Signatures in Spring Boot, you must tightly couple signature validation with request throttling, replay protection, and strict authentication checks. Below are concrete code examples that demonstrate a hardened approach.
First, ensure each request includes a timestamp and a nonce, and validate them before performing Hmac verification. This prevents replay attacks and ensures freshness. Configure a short tolerance window (for example, 5 minutes) and store used nonces temporarily to reject duplicates.
@Component
public class HmacValidator {
private final String secret;
private final Cache nonceCache = ConcurrentHashMap.newKeySet();
public boolean validate(String username, long timestamp, String nonce, String receivedSignature, String payload) {
// Reject old timestamps
if (System.currentTimeMillis() - timestamp > 300_000) {
return false;
}
// Reject reused nonces
if (!nonceCache.add(nonce)) {
return false;
}
String computed = computeHmac(username, timestamp, nonce, payload);
return MessageDigest.isEqual(computed.getBytes(StandardCharsets.UTF_8),
receivedSignature.getBytes(StandardCharsets.UTF_8));
}
private String computeHmac(String username, long timestamp, String nonce, String payload) {
String data = username + timestamp + nonce + payload;
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(key);
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hash);
}
}
Second, enforce rate limiting at the controller level based on username or IP, and integrate it with the validation flow. Use a token bucket or sliding window algorithm to limit attempts per minute. Spring Security and resilience libraries can help, but ensure limits apply before expensive Hmac computations for invalid requests.
@RestController
@RequestMapping("/api/auth")
public class AuthController {
private final HmacValidator validator;
private final RateLimiter rateLimiter;
public AuthController(HmacValidator validator, RateLimiter rateLimiter) {
this.validator = validator;
this.rateLimiter = rateLimiter;
}
@PostMapping("/login")
public ResponseEntity> login(@RequestBody LoginRequest request,
@RequestHeader("X-Timestamp") long timestamp,
@RequestHeader("X-Nonce") String nonce,
@RequestHeader("X-Signature") String signature) {
// Apply rate limit first
if (!rateLimiter.allow(request.getUsername())) {
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).build();
}
if (!validator.validate(request.getUsername(), timestamp, nonce, signature, request.getPassword())) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
// Issue token on success
return ResponseEntity.ok(Collections.singletonMap("token", ""));
}
}
Finally, bind the Hmac scope to the user context by including the username within the signed payload and validating it matches the authenticated subject. Avoid including sensitive secrets in URLs or logs, and prefer POST bodies with strict content-type checks. middleBrick’s scans can verify that these controls are present by checking for timestamp/nonce enforcement, rate limiting, and secure comparison patterns.