Padding Oracle in Express with Hmac Signatures
Padding Oracle in Express with Hmac Signatures — how this specific combination creates or exposes the vulnerability
A padding oracle attack can occur in an Express API when ciphertext is processed in a way that leaks information about padding validity during decryption or verification. This often happens when an HMAC-based strategy is used to sign a token or payload, but the server does not enforce constant-time comparison and exposes distinct error paths for padding failures versus signature mismatches.
Consider an Express route that receives an encrypted token, decrypts it, and then verifies an HMAC before processing business logic. If the decryption step throws a padding error and the server responds with a different status code or message than when the HMAC verification fails, an attacker can iteratively send modified ciphertexts and observe responses to infer the plaintext. Even when Hmac Signatures are used to provide integrity, a non-constant-time verification or a decryption step prior to verification can create a side-channel that enables a padding oracle.
For example, an API accepting JSON Web Encryption (JWE) or a custom encrypted+signed format may first decrypt using AES with PKCS7 padding and then verify an HMAC-SHA256 over the ciphertext or the plaintext. If the decryption fails due to invalid padding and the server returns a 400 with Invalid padding, whereas a bad HMAC yields a 401 with Invalid signature, the difference becomes an oracle. An attacker who can craft ciphertexts and observe these responses can recover the plaintext without needing the secret encryption key, leveraging the padding oracle to decrypt iteratively. This is a real concern when Express endpoints process encrypted and signed tokens outside of a verified library that handles both in a single, atomic operation.
Using strong, standard libraries does not automatically prevent this if the application logic separates decryption and HMAC verification into distinct steps with different error handling. The attacker does not need to understand internal architecture; they only need to observe that certain malformed ciphertexts produce different responses, enabling adaptive chosen-ciphertext attacks. Even when Hmac Signatures are used to ensure integrity, failing to validate the signature before attempting decryption, or mixing error types, can expose a padding oracle.
Hmac Signatures-Specific Remediation in Express — concrete code fixes
To mitigate padding oracle risks when using Hmac Signatures in Express, design the endpoint so that verification and decryption are performed atomically by a trusted library, and ensure error paths do not distinguish between padding failures and signature or HMAC failures. Always compare HMACs in constant time and return a uniform error response for any invalid input.
Below is a secure Express example using jsonwebtoken with an HMAC secret (HS256). The library verifies the signature before any processing and returns a single generic error for invalid tokens, avoiding information leakage.
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
const HMAC_SECRET = process.env.HMAC_SECRET;
if (!HMAC_SECRET) {
throw new Error('HMAC_SECRET must be set');
}
app.post('/api/verify', (req, res) => {
const { token } = req.body;
if (!token || typeof token !== 'string') {
return res.status(400).json({ error: 'Bad request' });
}
try {
// Verify HMAC signature and decode payload in one step
const decoded = jwt.verify(token, HMAC_SECRET, { algorithms: ['HS256'] });
// Proceed with normalized, validated payload content
return res.json({ ok: true, payload: decoded });
} catch (err) {
// Use a generic message and status to avoid leaking error type
return res.status(401).json({ error: 'Unauthorized' });
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
If your flow requires encrypted payloads, prefer a single JWE/JWS library operation or ensure the decryption function is only called after a valid HMAC check, and that errors are indistinguishable. Never perform decryption before verifying integrity when padding is involved, and avoid branching logic based on specific error messages like ERR_OSSL_PADDING.
For API security scanning, tools such as the middleBrick CLI can be integrated into your workflow: use middlebrick scan <url> from the terminal to detect endpoints where error handling or stepwise verification might introduce padding oracle risks, and include checks in CI/CD with the GitHub Action to fail builds if security scores drop below your chosen threshold.