Bleichenbacher Attack in Hapi with Jwt Tokens
Bleichenbacher Attack in Hapi with Jwt Tokens — how this specific combination creates or exposes the vulnerability
A Bleichenbacher attack is a padding oracle attack against RSA-based encryption or signature schemes. When Hapi applications use JWT tokens with RSA signatures (for example, RS256) and do not enforce strict verification or leak timing differences during signature validation, the combination can expose a padding oracle that allows an attacker to recover the private key or forge tokens.
In Hapi, developers often rely on community plugins or built-in validation helpers to verify JWTs. If these integrations use default or minimal validation settings, they may accept tokens with different header algorithms (e.g., switching from RS256 to HS256) or accept tokens with invalid padding. When the server responds with distinct timing or error messages for valid versus invalid padding during RSA decryption, an attacker can iteratively send modified ciphertexts and observe responses, gradually decrypting the token without knowing the private key.
Example scenario: A Hapi server uses hapi-auth-jwt2 and verifies tokens with a public key but does not explicitly set algorithms. An attacker intercepts a valid RS256-signed JWT, modifies the header to use HS256, and re-signs the token using a known secret (if the server also accepts symmetric keys). Alternatively, in an RSA encryption context, the attacker sends many ciphertexts and observes whether padding errors differ from signature verification errors, enabling decryption.
Key contributing factors in Hapi include:
- Accepting tokens with algorithm "none" or failing to restrict allowed algorithms.
- Returning different HTTP status codes or response bodies for padding errors versus signature mismatches.
- Using public keys that do not enforce strict OAEP or PSS padding checks during verification.
Because middleBrick tests unauthenticated attack surfaces, scans can detect indicators such as inconsistent error responses, missing algorithm restrictions, and exposed public endpoints that facilitate such oracle behavior. Findings highlight these risks with severity ratings and remediation guidance mapped to OWASP API Top 10 and relevant compliance frameworks.
Jwt Tokens-Specific Remediation in Hapi — concrete code fixes
Remediation focuses on strict algorithm enforcement, constant-time comparison, and proper key usage. Below are concrete Hapi examples that mitigate Bleichenbacher-style padding oracle risks when working with JWT tokens.
1. Explicitly restrict allowed algorithms and avoid automatic algorithm negotiation. Use the hapi-auth-jwt2 options to specify RS256 only and provide a proper public key.
const Hapi = require('@hapi/hapi');
const hapiJwt = require('hapi-auth-jwt2');
const validate = async (decoded, request, h) => {
// Perform additional application-level checks here (e.g., scope, issuer)
return { isValid: true, credentials: decoded };
};
const init = async () => {
const server = Hapi.server({ port: 4000, host: 'localhost' });
await server.register(hapiJwt);
server.auth.strategy('jwt', 'jwt', {
key: process.env.JWT_PUBLIC_KEY, // PEM-formatted RSA public key
verifyOptions: { algorithms: ['RS256'] }, // enforce RS256 only
validate: validate
});
server.auth.default('jwt');
server.route({
method: 'GET',
path: '/secure',
handler: (request, h) => {
return { message: 'Authenticated access granted', user: request.auth.credentials };
}
});
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', (err) => {
console.error(err);
process.exit(1);
});
init();
2. Ensure your RSA public key uses proper padding and that verification does not leak timing differences. Do not rely on default libraries that may perform non-constant-time checks. Use Node.js crypto with explicit padding schemes and avoid returning distinct messages for padding vs signature errors.
3. When using encryption (e.g., JWE), enforce strong key management and specify compact serialization with explicit algorithms. Do not accept tokens with missing or mismatched key management headers.
// Example: strict JWT verification with explicit algorithms and key handling
const jwt = require('jsonwebtoken');
const publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----`;
const verifyToken = (token) => {
try {
const decoded = jwt.verify(token, publicKey, {
algorithms: ['RS256'],
complete: false
});
return { valid: true, payload: decoded };
} catch (err) {
// Use a generic error to avoid leaking validation details
return { valid: false, error: 'invalid_token' };
}
};
// Usage in Hapi handler
// const result = verifyToken(authHeader);
4. Rotate keys regularly and monitor for unexpected algorithm usage. Use middleBrick's continuous monitoring (Pro plan) to detect configuration drift and alert on risk changes in your API security posture.
By combining strict algorithm policies, constant-time validation, and robust key management, Hapi applications can effectively neutralize Bleichenbacher-style padding oracle risks associated with JWT tokens.