HIGH padding oracleexpresshmac signatures

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.

Frequently Asked Questions

Why does separating decryption and HMAC verification create a risk in Express APIs?
Separating these steps with distinct error messages or status codes can act as a padding oracle: an attacker can send modified ciphertexts and learn whether failures are due to padding or signature issues, enabling adaptive chosen-ciphertext attacks. Always verify HMAC before decryption and use constant-time, unified error handling.
Can using HS256 with jsonwebtoken eliminate padding oracle risks entirely?
HS256 with proper library usage significantly reduces risk because the signature is verified before processing, but padding concerns can still arise if the payload is additionally encrypted using block modes with padding and error handling is not uniform. Use atomic operations and consistent error responses to stay safe.