Skip to content

CWE-329: Generation of Predictable IV with CBC Mode

Overview

CBC (Cipher Block Chaining) mode requires a random, unpredictable Initialization Vector (IV) for each encryption operation. Using static, sequential, or predictable IVs enables plaintext recovery through IV manipulation attacks, completely breaking encryption security even with correct key.

OWASP Classification

A04:2025 - Cryptographic Failures

Risk

High: Predictable IVs in CBC mode enable chosen-plaintext attacks, plaintext recovery by manipulating IV, pattern detection in encrypted data, and complete compromise of confidentiality. Reusing IVs with same key allows attackers to XOR ciphertexts to reveal plaintext relationships.

Remediation Steps

Core principle: CBC requires a fresh unpredictable IV for each encryption under the same key. AEAD/nonce-based modes such as GCM require nonce uniqueness and should normally use the mode's recommended nonce size.

Locate the predictable IV usage in your code

  • Review the flaw details to identify the specific file, line number, and code pattern using CBC mode
  • Identify how the IV is generated: static byte array, sequential counter, timestamp, or derived from plaintext
  • Determine if the IV is reused across multiple encryptions with the same key
  • Trace the encryption flow to see where IV is created and used

Use random IV for each encryption (Primary Defense)

  • Generate cryptographically random IV: Use SecureRandom (Java), os.urandom/secrets (Python), crypto.randomBytes (Node.js) for each CBC encryption operation
  • Use platform CSPRNG APIs: SecureRandom/os.urandom/crypto.randomBytes provide cryptographically secure random bytes
  • CBC IV must be same size as block size: 16 bytes (128 bits) for AES
  • Store/transmit IV with ciphertext: Prepend IV to ciphertext (IV doesn't need to be secret, can be transmitted in clear)
  • AES-GCM (recommended - includes authentication): Provides both confidentiality and integrity, prevents tampering
  • ChaCha20-Poly1305 (modern, fast): Alternative to AES-GCM, faster on systems without AES hardware acceleration
  • Manage nonces explicitly unless your library does it for you: Many APIs require the caller to provide the GCM nonce; use a 96-bit nonce and never repeat it with the same key
  • Provides both confidentiality and integrity: Detects if ciphertext has been modified or IV manipulated

Never reuse IVs

  • Generate new random IV per encryption: Each encryption operation must use a unique, unpredictable IV
  • Don't use counter-based IVs for CBC: CBC IVs must be unpredictable before the plaintext is chosen
  • Don't derive IV from plaintext: IV must be independent of the data being encrypted
  • IV must be unpredictable before encryption: Attacker should not be able to predict IV before encryption happens

Proper IV handling

  • Prepend IV to ciphertext for storage/transmission: Store as [IV][ciphertext] or [IV_length][IV][ciphertext]
  • IV is not secret, can be transmitted in clear: No need to encrypt or hide the IV
  • Validate IV is correct size: Check IV is 16 bytes for AES before using
  • Never encrypt IV itself: IV should be prepended in plaintext to ciphertext

Test the IV randomness fix

  • Verify new IV is generated for each encryption (check multiple encryptions produce different IVs)
  • Test that same plaintext produces different ciphertext each time (due to random IV)
  • Verify IV is prepended to ciphertext and can be extracted for decryption
  • Test decryption works correctly with random IVs
  • Verify IV/nonce generation follows the mode requirements and handles uniqueness correctly; statistical tests cannot prove cryptographic safety
  • Re-scan with security scanner to confirm the issue is resolved

Common Vulnerable Patterns

  • static byte[] IV = {0,0,0,0...}
  • Using same IV for all encryptions
  • Sequential/counter IVs
  • Deriving IV from timestamp or plaintext
  • Empty/zero IV

Additional Resources