SecureBlockLog inStart a pentest
Vulnerability Repository
HighCryptography

Padding Oracle Attack

Applications that leak padding validation errors during decryption allow attackers to decrypt and forge ciphertext without knowing the encryption key.

CVSS 7.5CWE CWE-326OWASP A02:2021 — Cryptographic Failures

Description

A padding oracle attack is a cryptographic side-channel attack that exploits the error behavior of a system performing block cipher decryption with padding validation — typically PKCS#7 padding with AES-CBC or 3DES-CBC. When a decryption operation returns a different response depending on whether the padding was valid or invalid, the system is acting as an "oracle": it answers yes/no questions about the padding of a modified ciphertext. An attacker can use this oracle to decrypt any ciphertext and forge valid ciphertext, all without knowing the encryption key.

The vulnerability is classified under CWE-326 — Inadequate Encryption Strength and A02:2021 — Cryptographic Failures because the root cause is using an unauthenticated cipher mode (CBC) that does not detect tampering before decryption. The correct solution is to use authenticated encryption (AES-GCM or ChaCha20-Poly1305), which produces a MAC that must be verified before decryption — making tampering immediately detectable without revealing padding information.

The most famous real-world manifestation is the POODLE attack (2014) against SSL 3.0's CBC padding, and the ASP.NET padding oracle vulnerability (MS10-070) which affected millions of .NET web applications. The attack was formalized by Serge Vaudenay in 2002.

How It Works

Consider an encrypted session token that the server decrypts using AES-128-CBC. The attacker intercepts or has access to a valid ciphertext. In CBC mode, each plaintext block is XOR'd with the previous ciphertext block before decryption. For PKCS#7 padding, if the last block decrypts to bytes ending in \x01, padding is valid; \x02\x02 is valid; etc.

The attacker modifies the second-to-last ciphertext block, byte by byte, and sends the modified ciphertext to the server. The server decrypts and checks padding:

  • If the server returns a padding error (or different HTTP status, timing, or response) → padding was invalid.
  • If the server returns a normal response (even an application error) → padding was valid.

Through this binary oracle, the attacker can determine the plaintext value of each byte through the following reasoning:

For the last byte of plaintext:
Try modifying ciphertext byte 15 from 0x00 to 0xFF.
When server says "valid padding", the last decrypted byte = 0x01.
Therefore: plaintext_byte = 0x01 XOR ciphertext_modification XOR original_ciphertext_byte

Repeating this for all 16 bytes of a 128-bit block, and for each block in sequence, the attacker recovers the full plaintext in at most 256 × block_size requests — typically a few thousand HTTP requests. The PadBuster tool automates this attack:

padbuster http://app.example.com/profile <encrypted_cookie> 8 -encoding 1 -cookies "auth=<encrypted_cookie>"

Forging ciphertext works in reverse: the attacker knows how to produce any desired intermediate decryption value and can XOR the preceding ciphertext block to control the decrypted plaintext, allowing them to create valid encrypted tokens for arbitrary values (e.g., admin=true).

Impact

  • Session token decryption — encrypted session cookies or authentication tokens are decrypted, revealing session content and user identities.
  • Authentication bypass — forged ciphertext allows creation of valid encrypted tokens with attacker-controlled plaintext (e.g., admin=1).
  • Sensitive data exposure — any data encrypted with the vulnerable scheme (order IDs, user parameters, API tokens) can be decrypted.
  • Account takeover — if password reset tokens or remember-me cookies are encrypted with a vulnerable cipher, they can be forged.
  • Encrypted parameter manipulation — applications that encrypt URL parameters to prevent tampering (a flawed design) are completely defeated.

Detection

  1. Identify encrypted opaque values in cookies, URL parameters, and request bodies. These are candidates for padding oracle testing — especially if they appear to change in response to user actions.
  2. Send modified ciphertext and observe responses — flip bits in the encrypted value and note whether the server returns different HTTP status codes, response bodies, error messages, or timing differences. Consistent differentiation indicates an oracle.
  3. Use PadBuster to automate exploitation once an oracle is identified — it handles the full byte-by-byte decryption and optionally encryption of arbitrary plaintext.
  4. Test with Burp Suite — the Intruder and Sequencer tools help generate systematic modifications to identify whether response differences correlate with padding validity.
  5. Check for CBC mode usage — review the application's cryptographic libraries for AES-CBC or 3DES-CBC usage without a MAC (HMAC-SHA256 or equivalent). Any CBC usage without authentication should be investigated.
  6. Test TLS configuration for POODLE susceptibility — testssl.sh checks for SSL 3.0 support and CBC padding oracle conditions.

Remediation

Use authenticated encryption exclusively. Replace all AES-CBC and 3DES-CBC usage with AES-GCM or ChaCha20-Poly1305. These modes produce an authentication tag that must be verified before decryption — ciphertext tampering is detected immediately without revealing padding information:

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

key = os.urandom(32)   # AES-256
nonce = os.urandom(12)
aesgcm = AESGCM(key)

# Encrypt
ciphertext = aesgcm.encrypt(nonce, plaintext, associated_data)

# Decrypt — raises InvalidTag exception if tampered
plaintext = aesgcm.decrypt(nonce, ciphertext, associated_data)

If CBC must be used temporarily, implement Encrypt-then-MAC: compute HMAC-SHA256 over the entire ciphertext (including IV) and verify it in constant time before attempting decryption. Never decrypt ciphertext that fails the MAC check.

Return uniform error responses. All decryption failures — whether due to padding errors, authentication tag failures, or application errors — must return identical responses with identical timing. Use a constant-time comparison for MAC verification.

Disable SSL 3.0 and TLS 1.0 to prevent POODLE and BEAST attacks. Enforce TLS 1.2+ with AEAD cipher suites only.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping