skip to content

Replay and Freshness

A second copy of a message that says approve, pay or grant is worth what the first was, so idempotency helps the attacker. Interviewers test what refusing a duplicate actually costs the receiver.

on this pageshow

explore

questions

4

A partner's signed, TLS-protected payment instruction is captured and sent twice — why does the second copy pay?

level: juniorimportance: must knowfreq 70%

answer

  1. Two different properties, one missing
  2. A signature has no memory
  3. The second copy is genuine, not forged
  4. Only the receiver can know it is a repeat
  5. Freshness is state, not a message field

basics

~20 s

Signing proves who composed the message and that nobody altered it; encryption hides it from others. Neither says this copy is the first. Only receiver-held state — a counter, remembered identifier or time window — refuses a duplicate.

solid answer

~50 s

A signature is a property of the bytes, not of the delivery. Verifying it tells the receiver that the partner composed exactly this instruction and that nothing was changed in flight; the transport tells it nobody else could read or tamper with it. A byte-identical second copy satisfies both checks perfectly, because it *is* the same authentic message — which is exactly why replay works and why more cryptography on the message alone never fixes it. Freshness is not a property a message can carry; it is a comparison the receiver makes against something it remembers. So the receiver has to hold state: a highest-accepted counter per sender, a set of recently seen message identifiers, or a signed timestamp checked against a narrow window. Notice too that the replayer needs no exploit — the partner's own integration engineer already stores valid copies.

go deeper

for a junior

Be ready to say plainly what a signature proves — who composed it and that it was not altered — and what it does not prove: that this delivery is the first. Naming freshness as a separate property is most of the answer.

for a middle

Explain why a byte-identical copy passes every cryptographic check, then name the receiver state that could refuse it: a counter, a remembered-identifier set, or a signed timestamp checked against a window.

for a senior

Show where the replayer actually sits — a party that lawfully holds valid copies — so hardening keys or the network changes nothing. Say what the receiving service must persist, and survive a restart with, before it can refuse a second copy.

for a principal

Own the framing that freshness is receiver-held state with a running cost in storage, clock discipline and false rejections, and that this cost sits on the receiving side of a partner contract even when the duplicate originates with the sender.

## The claim being corrected The sentence an API designer says, almost word for word, is: *"the message is signed and it goes over TLS, so it cannot be replayed."* Both halves of that sentence are true statements about different properties, and neither of them is freshness. **What a signature proves.** A signature is computed over a fixed sequence of bytes. Verification succeeds when the bytes presented now are the bytes the holder of the private key signed. It therefore establishes two things: *origin* (someone with that key produced this content) and *integrity* (nothing was altered since). It says nothing about when the message was produced, how many times it has been delivered, or whether the receiver has already acted on it. Signature verification is a pure function of the message and the key; it has no memory, so it cannot possibly answer a question about history. **What the transport proves.** TLS gives confidentiality and integrity for a *connection*, and it does prevent an attacker from re-injecting a captured record inside that connection — record sequencing makes duplicate records fail. But an application message resent over a brand-new connection is not a duplicated record. It is a fresh, legitimate, correctly authenticated connection carrying a fresh, legitimate record whose plaintext happens to be a message the receiver has seen before. TLS has no idea what an application-level payment instruction is, so it cannot deduplicate one. ## Freshness is receiver-held state, not a message property The core idea to internalise: *no message can prove it is the first copy of itself*. Any bit pattern that says "this is new" can be copied along with the rest of the message. The only way to distinguish a first delivery from a second is for the receiver to compare the arriving message against something it already knows. That "something" is state, and it costs storage, durability and discipline: - **A monotonic counter or sequence number per sender.** The receiver keeps the highest value it has accepted and refuses anything at or below it. Cheap — one integer per sender — but it demands ordered delivery, a single logical sender per counter, and durability across a restart. - **A remembered-identifier set.** The receiver records a unique identifier from each accepted message and refuses a repeat. Tolerant of out-of-order and parallel delivery, but the set grows, so it needs a retention bound — and the bound is only safe if something else refuses messages older than the retention. - **A timestamp window.** The message carries a signed timestamp; the receiver refuses anything outside a tolerance. This bounds how long a captured copy stays useful, but on its own it permits unlimited replay *inside* the window, and it buys that with a requirement for synchronised clocks on both sides. In practice the standard composition is a narrow window plus an identifier set retained at least as long as the window: a copy is then either too old, or already remembered. ## Who actually replays The mental image of a wiretapper capturing ciphertext is the wrong one, and it is why the cryptographic answer feels sufficient. The people best placed to resend a valid payment instruction are the ones who legitimately hold valid copies: an integration engineer at the sending partner whose service stores every outbound message, a retry queue that was drained twice, a restored backup of the message store, a support tool with a "resend" button. Nothing is forged, nothing is decrypted, no boundary is crossed — which is exactly why every origin check passes and why key hygiene, mutual authentication and network segmentation change nothing here. This also explains the classification error that keeps teams stuck. A **forgery** fails verification, so the remedy lives in the cryptography: better keys, stricter verification, better key custody. A **replay** passes verification, so the remedy lives in the receiver's memory. Teams that file replay under "crypto problem" keep strengthening the part that already worked. ## The consequence in a machine-to-machine setting When the message says *approve*, *pay* or *actuate* rather than *authenticate*, a second execution is not a nuisance — it is a second payment, a second valve command, a second grant. There is no human in the loop to notice the repetition, the partner's system believes it sent one instruction, and the duplicate is often discovered days later by the other side's reconciliation and reported to you rather than found by you. The correct answer to the designer, then, is one sentence with a cost attached: *freshness is state the receiver must keep, and you have not yet decided which state, how long you keep it, or what happens when the store restarts.*

  • Does putting a timestamp in the signed body, on its own, stop the replay?
    Not by itself. A timestamp only helps if the receiver enforces a window and refuses anything outside it, and even inside the window the same copy can be sent again and again. A window bounds how long a captured message stays useful; it does not make a copy distinguishable from the original. The usual pairing is a narrow window plus a remembered-identifier set retained at least as long as that window.
  • Who is best placed to replay a partner's payment instruction, and what does that tell you?
    Not an interceptor on the wire — the transport makes that hard. It is whoever already holds valid copies: the sending partner's integration engineer, a retry queue drained twice, a restored message store. Nothing is forged or decrypted, so every origin check passes. That tells you the control which matters is receiver-side freshness state, not stronger cryptography and not a tighter network boundary.
  • Is a replayed message a forgery?
    No, and the distinction picks the fix. A forgery fails verification, so the remedy is in the keys and the verification path. A replay is genuine and passes every check, so the remedy is memory at the receiver. Teams that classify replay as forgery keep hardening the cryptography that was never broken and remain fully exposed.

A signed cheque proves who wrote it and that the amount was not altered. It says nothing about whether the bank already cashed it — that is the bank's ledger, not the cheque.

saying these in an interview costs you the question

  • Says TLS prevents replay because the channel is encrypted
  • Believes a valid signature implies the message is new
  • Assumes the replayer must decrypt or forge something first
  • Treats replay as a cryptography bug rather than missing receiver state
  • Thinks mutual authentication makes duplicate delivery impossible

context

open as a page

How do a monotonic counter, a remembered-message-id set and a clock window differ in what the receiver must keep?

level: middleimportance: must knowfreq 54%

basics

~20 s

A counter stores one number per sender but needs ordered delivery and must survive restarts. An identifier set tolerates disorder but needs storage and a retention bound. A clock window needs synchronised clocks and, alone, still permits replay inside it.

open as a page

Your receiver dedupes on an unsigned request-id header while the signature covers only the body — what replay is still possible?

level: middleimportance: should knowfreq 42%

basics

~20 s

The header sits outside the signed bytes, so whoever holds the message changes that value and resends the identical body. The deduplication key never matches, the signature still verifies, and the instruction executes again. The key must live inside the signed content.

open as a page

A payment partner demands a 24-hour freshness window so its late retries are never rejected — what do you agree to?

level: principalimportance: should knowfreq 30%

basics

~20 s

Agree only if remembered-identifier retention is extended to cover the whole window, because a window without matching memory is pure exposure. Price the extra storage, write the retention bound into the interface agreement, and keep partner test keys unacceptable in production.

open as a page