A predictable iv attack goes after a detail that looks harmless: the initialization vector that CBC mode mixes into the first block. If an attacker can guess the IV a message will use before it is sent, and can influence even a little of the plaintext, they can turn encryption into a yes or no oracle and confirm their guesses about the secret one piece at a time. This post explains why an unpredictable IV is part of the security promise, not a throwaway value, and how a predictable one breaks it.
What the IV is supposed to do
CBC encrypts the first plaintext block like this:
C[0] = E(key, P[0] XOR IV)
The IV exists so that encrypting the same message twice produces different ciphertext. Without it, two identical login requests would encrypt to identical bytes, and an observer would learn they were the same. That property has a name, semantic security: ciphertext should leak nothing about plaintext, not even whether two messages match. The IV is what delivers it, and the IV only works if the attacker cannot predict it in advance.
Why a predictable iv attack breaks semantic security
There are two flavors, and both come from the IV being known ahead of time.
A reused IV leaks equality
If every message uses the same fixed IV, then identical first blocks always encrypt to identical ciphertext. The first block behaves just like ECB mode: equal plaintext in, equal ciphertext out. An attacker watching traffic can tell when two messages start with the same block, which is enough to fingerprint a repeated command, a known header, or a session that keeps resending the same secret.
A predictable IV enables a confirmation oracle
This is the sharper problem, the class behind the chosen boundary attacks on older TLS. Suppose an attacker can both see the IV that will be used next and inject part of the plaintext that gets encrypted alongside a secret they want to read. They pick a guess for one unknown byte, then craft their injected block so that, if the guess is right, its input to the cipher equals the secret block’s input to the cipher.
guess input: P_guess XOR IV_next secret input: S XOR IV_secret
Because the attacker knows both IVs, they choose P_guess so these two inputs are equal exactly when P_guess carries the correct secret value. Equal inputs to the same block cipher give equal ciphertext blocks. So the attacker watches the two ciphertext blocks: a collision means the guess was right, no collision means it was wrong. One bit of feedback per try, and with the boundary lined up so only one byte is unknown at a time, the full secret falls out byte by byte.
An unpredictable IV keeps encryption honest by making every first block a fresh surprise. A predictable IV lets an attacker line up a guess against a secret and read the answer off a collision.
Picture a SaaS app called Acme Notes that keeps a CBC encrypted auth token in a cookie and reuses a counter as the IV, so the next IV is simply the last one plus one. An attacker who can trigger encryptions and observe the ciphertext now knows each IV before it is used. That is the exact condition the confirmation oracle needs. The token was never read directly, yet it leaks.
How predictable IVs sneak into code
Nobody sets out to ship a guessable IV. It arrives through shortcuts that look reasonable:
- A constant IV. A developer hardcodes a zero IV or a fixed string because the API demanded one and random felt like extra work. Now every message shares it.
- A counter or timestamp. An IV built from a sequence number or the clock is unique but fully predictable, which defeats the confirmation defense even though it never repeats.
- Chaining the last ciphertext block. Older protocols used the previous message’s final ciphertext block as the next IV. It is unique, but it is visible on the wire, so the attacker knows the next IV before sending.
- A weak random source. A non cryptographic generator, or one seeded from the time, produces IVs an attacker can reconstruct.
This sits right next to two other CBC failures. A cbc bit flipping attack abuses the same first block XOR to tamper with plaintext rather than read it, and aes gcm nonce reuse shows the same lesson in an authenticated mode, where repeating the value that should be unique collapses the guarantee. You can find more of these foundations under vulnerability basics, and the broader family sits in our cryptographic oracle attacks hub.
How to fix it
The rule is short: the IV must be unpredictable to anyone who does not hold the key, and fresh for every message.
- Generate the IV from a CSPRNG. Draw a new random IV for each message from the platform secure random source, never from a counter, a clock, or a previous ciphertext block.
- Send the IV in the clear, but pick it before you reveal it. The IV does not need to be secret. It needs to be unknown at the moment the attacker is choosing their injected plaintext. A per message random IV satisfies that.
- Prefer an AEAD mode. AES GCM or ChaCha20 Poly1305 take a nonce and add an authentication tag. They sidestep the chosen boundary problem and catch tampering at the same time, as long as you honor the unique nonce rule.
- Authenticate the ciphertext. Even with a good IV, unauthenticated CBC is still open to tampering. Pair it with a MAC or move to AEAD so integrity is covered too.
- Do not reuse IV and key together. A fresh key resets the whole space. Rotating keys limits how much any single weakness can expose.
The pattern is familiar by now. AES is fine and CBC is fine. The break is an assumption in the glue code, that the IV is just a formality you can fill with anything. Pick a predictable value and the whole mode quietly loses its meaning, while the encrypt call on the page still looks correct.
Finding this kind of flaw means reasoning about how an application builds each ciphertext, where its IV comes from, and whether an attacker could know that value ahead of time. That is exactly the assumption testing an autonomous researcher is built to do. Read more on our about page.
Frequently asked questions
What is a predictable IV attack?
It is an attack on CBC mode where the initialization vector can be guessed before a message is sent. CBC XORs the IV into the first plaintext block, and the IV exists so that encrypting the same message twice looks different. If an attacker knows the next IV and can inject part of the plaintext, they can craft a block that collides with a secret block only when their guess is correct, turning encryption into a yes or no oracle that leaks the secret one byte at a time.
Why does an IV need to be unpredictable?
Semantic security means ciphertext should leak nothing about plaintext, not even whether two messages match. The IV delivers that by making each first block fresh. A fixed or reused IV makes identical first blocks encrypt identically, leaking equality like ECB. A unique but guessable IV, such as a counter or the previous ciphertext block, lets an attacker line up a guess against a secret and confirm it, which is the chosen boundary class of attack.
How do predictable IVs end up in real code?
Through shortcuts that look fine. A hardcoded zero or constant IV, an IV built from a counter or timestamp, reusing the previous message’s last ciphertext block as the next IV, or drawing the IV from a weak non cryptographic random source. Each one is either repeated or guessable, and either condition is enough to undermine the mode.
How do you prevent a predictable IV attack?
Generate a fresh random IV for every message from a cryptographic random source, never from a counter, clock, or prior ciphertext. The IV can travel in the clear, it just has to be unknown while the attacker is choosing their input. Better still, use an AEAD mode like AES GCM or ChaCha20 Poly1305, which handles the unique value and also authenticates the ciphertext so tampering is caught too.
Put an autonomous researcher on your own systems
UnboundCompute is an autonomous security researcher that reasons about how an application fits together and proves the access control and injection bugs it finds. We are opening a small number of founding design partner seats: private early access pointed at a staging target you choose, and a say in what it looks for. If your team ships software worth pressure testing, apply to the design partner program.
