API Replay Attacks: REST API Prevention Guide (2026)
API Replay Attacks: REST API Prevention Guide (2026)
API security · Replay resistance · Updated September 2026

API Replay Attacks: How to Prevent Replay in REST APIs

Replay attacks are difficult because the request can be authentic. The token may be valid, the signature may verify, and the payload may be correct. The security failure is accepting the same proof or business action again. Strong protection combines freshness, uniqueness, sender binding, authorization, and retry-safe business logic.

An API replay attack reuses previously valid API material—such as a signed request, bearer token, JWT, webhook, authorization message, or transaction—so the server accepts it again. The key weakness is not necessarily broken cryptography. It is a missing check for freshness, uniqueness, sender binding, or one-time business intent.

Direct answer: A REST API prevents replay by combining HTTPS with request or proof freshness, a unique identifier such as a nonce or jti, server-side duplicate detection, sufficient cryptographic binding to the request, correct authorization, and idempotency or one-time state for operations that must not execute twice.

NIST defines replay attacks as replaying previously captured messages to masquerade as a legitimate claimant or verifier, and defines replay resistance as protection against captured authentication or access-control information being retransmitted for an unauthorized effect. The same security property applies naturally to APIs that carry signed HTTP messages, bearer tokens, webhooks, and state-changing business operations.

What Is an API Replay Attack?

Replay is different from request forgery. In a forgery, the attacker changes or creates material and tries to make it look legitimate. In a replay, the attacker often keeps the trusted material intact and exploits the server's willingness to accept it again.

API replay attack compared with related security problems
PatternWhat the attacker reuses or abusesPrimary defense question
Exact replayPreviously valid request, proof, token, or eventHas this proof expired or already been accepted?
Bearer-token replayA stolen access tokenIs the token constrained to the intended sender and audience?
Webhook replayA valid signed deliveryIs the signature fresh and the delivery/event ID new?
Business-action replaySame payment, refund, approval, or workflow intentShould the business effect be allowed to happen twice?

How Does a Replay Attack Work?

The mechanics vary, but the sequence is usually simple: obtain valid material, preserve what makes it acceptable, resend it, and rely on the verifier checking authenticity without checking enough freshness or prior use.

1. Obtain valid material

The material may come from a compromised client, leaked logs, malware, an exposed token, a copied webhook, a malicious endpoint, or another system that legitimately received the credential or message.

2. Preserve its trusted fields

The attacker keeps the token, signature, body, headers, target, or proof fields sufficiently intact for verification to succeed.

3. Submit it again

The same message may be replayed immediately, inside a freshness window, from another host, or against a different resource server if the proof is not properly scoped.

4. Exploit missing replay state

The server verifies that the proof is valid but does not recognize that the nonce, proof ID, event ID, token, or business operation was already used.

RFC 9421 explicitly describes signature replay. It recommends signing enough message components to distinguish one request from another, and supports a single-use nonce plus created and expires signature parameters to limit reuse.

Replay timeline

T0  Client sends a valid POST /payments
    signature = valid
    timestamp = fresh
    nonce = abc123

T1  Server accepts the payment

T2  Captured request is sent again

Vulnerable verifier asks:
    signature valid? yes
    token valid? yes

Replay-resistant verifier also asks:
    timestamp still acceptable?
    nonce or proof ID already seen?
    token bound to this sender and audience?
    business operation already completed?

Replay Attack vs Legitimate Retry vs Idempotency

Repeated requests are not automatically malicious. Mobile clients retry after timeouts, webhook providers redeliver, and payment SDKs may resend when they cannot tell whether the first request completed. Replay protection therefore has to preserve safe retry behavior.

How to distinguish replay attacks from legitimate retries
Repeated requestTypical intentSafe handling
Transport retryClient is unsure whether the first call succeededUse idempotency or transaction state to return the safe result without repeating the effect.
Webhook redeliveryProvider intentionally retries an unacknowledged eventReverify the delivery and deduplicate using the provider's event or delivery semantics.
Exact proof replayAttacker reuses the same proof or signed requestReject expired or already-seen nonce, jti, proof ID, or signed message.
Replay-like business abuseAttacker repeats harmful intent using new valid proofsUse authorization, idempotency, workflow state, rate controls, and runtime behavior detection.

Idempotency is not the same as replay resistance. Idempotency controls the business effect of retrying a state-changing operation. It does not by itself authenticate the caller or prove that a security proof is fresh. Stripe's API illustrates the difference: an idempotency key allows safe retries, while webhook and authentication controls address different security properties.

What Changed or Matters in 2026?

Replay resistance itself is not new, but the API-security guidance around it continues to mature. NIST's updated SP 800-228, updated March 13, 2026, adds API risks and recommended controls organized by API lifecycle stage. NIST also published the initial public draft of SP 800-228A in May 2026 with deployment guidance specifically for RESTful Web APIs. SP 800-228A is a draft, not a final standard.

For OAuth, the current security Best Current Practice is RFC 9700 (January 2025). It has a dedicated token replay prevention section and recommends sender-constrained access tokens such as mutual TLS or DPoP. For public-client refresh tokens, it requires sender constraint or refresh-token rotation.

Core API Replay Attack Prevention Controls

Replay resistance is strongest when each layer owns a clear part of the problem instead of forcing everything into one gateway rule or one application library.

Where API replay protection controls belong
LayerResponsibilityExamples
TransportProtect credentials and message content in transitTLS / HTTPS, mTLS
Identity / authorizationReduce usefulness of stolen tokensShort lifetimes, audience restriction, DPoP, certificate-bound tokens, refresh-token rotation
Request verificationVerify freshness and request bindingHTTP Message Signatures, HMAC schemes, signed timestamps, nonces
Replay stateRemember recently accepted identifiersNonce cache, proof-ID cache, event/delivery deduplication
Business applicationPrevent duplicate business effectsIdempotency keys, transaction IDs, spent-token state, workflow state
Runtime security / SOCDetect repeated intent and investigate abuseBehavior analytics, request/response context, SIEM evidence

Use TLS, but do not confuse encryption with replay resistance

HTTPS is foundational because it protects traffic in transit. It does not automatically make an application message single-use if valid material is obtained elsewhere. RFC 9421 explicitly treats TLS and HTTP message signatures as complementary controls.

Use a short freshness window

Signed creation and expiration times limit how long captured material remains useful. AWS Signature Version 4 provides a concrete operational example: AWS states that, in most cases, a signed request must reach AWS within five minutes of the request timestamp or it is denied. Your own window should be based on protocol behavior, clock accuracy, network conditions, and business risk—not copied blindly from another platform.

Use unique, verifiable identifiers

A nonce, proof ID, request ID, jti, event ID, or delivery ID only helps if the verifier can detect reuse during the relevant validity period. Distributed systems must keep this replay state consistent enough across replicas to prevent one server from accepting an identifier another server has already seen.

Bind the proof to the actual request

A signature that covers too little can be replayed in another meaningful context. Bind the proof to the method, target URI, relevant headers, body digest, freshness data, and authorization context required by your protocol. RFC 9421 specifically warns that insufficient component coverage can enable valid signatures to be reused on different messages.

Use sender-constrained OAuth tokens for high-value APIs

RFC 9700 recommends DPoP or mutual TLS to reduce misuse of stolen or leaked access tokens. Sender constraint changes the security model: possession of the token alone is no longer enough; the caller must also prove possession of the corresponding key material.

Keep one-time operations one time

Password resets, authorization-code redemption, enrollment challenges, approvals, and similar workflows require state that marks successful use. A cryptographically valid artifact can still be logically spent.

A Practical Replay-Resistant REST API Pattern

POST /v1/payments
Authorization: sender-constrained access token
X-Request-Timestamp: 2026-09-16T09:42:17Z
X-Request-Nonce: unique-random-value
Idempotency-Key: payment-attempt-7d91...
Signature-Input: method + path + timestamp + nonce + body-digest
Signature: cryptographic proof over required components

Server-side validation order
1. Require HTTPS.
2. Authenticate the caller.
3. Verify the signature or proof and required component coverage.
4. Check timestamp / created / expires freshness.
5. Reject a nonce or proof ID that has already been accepted.
6. Verify token audience and sender binding when used.
7. Apply authorization and business rules.
8. Apply idempotency or one-time state for the business operation.
9. Process the request.
10. Record replay-relevant evidence without logging secrets.
Design rule: a timestamp without duplicate tracking can still allow many replays inside the accepted window. A nonce without cryptographic binding may be replaceable. Idempotency without authentication can still process an unauthorized request. The controls are complementary.

OAuth, JWT, DPoP, and mTLS Replay Protection

Bearer tokens are replayable if stolen

Bearer tokens intentionally make possession sufficient for use. RFC 9700 therefore recommends audience restriction and sender-constrained tokens for cases where access-token replay is a meaningful risk.

JWT jti can support replay detection

RFC 7519 defines jti as a unique JWT identifier and notes that it can be used to prevent replay. The claim does not create replay protection by itself; the receiver must enforce uniqueness or another policy that makes repeated use unacceptable.

DPoP binds the token to a key and the proof to a request

RFC 9449 requires DPoP proofs to contain a unique jti, the HTTP method (htm), target URI (htu), and issue time (iat); protected-resource proofs also bind to the access token using ath. Servers can retain proof identifiers for the acceptance window and reject reuse. DPoP can also use a server-provided nonce when stronger freshness control is needed.

mTLS certificate-bound tokens reduce stolen-token reuse

RFC 8705 binds an OAuth access token to the client's certificate so a resource server can require proof of possession of the corresponding private key. This reduces the value of a stolen token to a party that does not possess that key.

Refresh-token rotation helps reveal replay

RFC 9700 requires public-client refresh tokens to be sender-constrained or rotated. With rotation, reuse of an invalidated refresh token can reveal that the token was copied and used by more than one party.

Webhook Replay Protection

Webhook security needs both authenticity and delivery semantics. Verify the provider's signature first, then apply freshness and deduplication rules supported by that provider.

Stripe

Stripe signs a timestamp inside the Stripe-Signature material and documents a default five-minute tolerance in its libraries. It also generates a new signature and timestamp for each retry. That means receivers should validate the current signature and still use event/business identifiers where they need idempotent processing.

GitHub

GitHub recommends validating X-Hub-Signature-256 and using X-GitHub-Delivery to ensure delivery uniqueness. A requested redelivery keeps the same delivery identifier, which makes deduplication semantics explicit.

How to Test Replay Resistance Safely

Replay testing should be performed only in systems you are authorized to test, preferably in a staging or isolated environment with synthetic data and clear stop conditions.

  1. Send one known-safe state-changing request and record the expected result.
  2. Repeat the exact request inside the normal acceptance window.
  3. Confirm the application either rejects the reused proof or returns the original idempotent result without repeating the business effect.
  4. Repeat after the freshness window and confirm the proof is rejected.
  5. For DPoP or nonce-based designs, confirm reuse of the same proof identifier is rejected according to the system's policy.
  6. Verify behavior across replicas or regions so duplicate tracking is not local to only one server.
  7. Confirm logs contain identifiers useful for investigation without storing bearer tokens, private keys, raw secrets, or unnecessary sensitive payloads.

Runtime Detection: Where Ammune Fits

Protocol-level replay prevention belongs in the API, gateway, authorization server, or identity layer. Runtime security complements those controls by looking for suspicious repeated intent when the attacker changes the outer request, obtains new credentials, regenerates signatures, or otherwise avoids an exact byte-for-byte duplicate.

Ammune can support that monitoring layer by analyzing live API requests and responses, API behavior, repeated actions or sequences, sensitive-data context, and security events that can be forwarded into SIEM and incident-response workflows. This should complement—not replace—nonces, freshness checks, sender-constrained tokens, replay caches, authorization, and idempotency.

Useful runtime signals for suspected API replay activity
SignalWhy it mattersUseful evidence
Repeated high-value actionMay indicate exact replay or repeated business intentEndpoint, method, principal, transaction/event ID, result
Same proof identifierStrong indicator when the identifier is meant to be single-useNonce, jti, DPoP proof ID, webhook delivery ID
Same token from changing contextsCan indicate credential theft or replayToken subject, audience, client identity, network/device context
Repeated action with fresh proofsExact replay controls may pass while business abuse continuesSequence, object IDs, rate, response data, user/session correlation

Related Ammune guidance: API runtime security protection, business-logic abuse detection, rate limiting versus behavior detection, and SIEM log forwarding formats.

Incident Response for Suspected Replay Activity

  1. Confirm the repeated effect. Determine whether the system executed the same operation twice or merely received a safe retry.
  2. Identify the reused trust material. Correlate request IDs, nonce/proof IDs, token subject and audience, jti, webhook delivery ID, idempotency key, and transaction identifiers.
  3. Contain credentials where necessary. Revoke or rotate compromised tokens, keys, sessions, or webhook secrets according to the affected protocol.
  4. Close the protocol gap. Add or tighten freshness, replay state, sender constraint, audience restriction, or one-time semantics.
  5. Protect the business workflow. Add idempotency or transaction-state checks where repeated execution is unsafe.
  6. Hunt for related activity. Search for the same principal, proof identifiers, endpoints, objects, or transaction patterns across the relevant time window.

For broader investigation workflow, see the API security incident response playbook.

Common Replay-Prevention Mistakes

Timestamp only

A timestamp limits replay time but can still allow repeated use inside the accepted window.

Nonce without storage

A unique value does not prevent reuse unless the verifier can recognize that it has already been accepted.

Local replay cache only

Multi-node systems can accept the same proof on different replicas if replay state is not shared appropriately.

Signing too little

If method, target, body, or important context is not covered, a valid signature may remain portable to another request.

Long-lived bearer tokens

A long token lifetime increases the opportunity to reuse a stolen token when no sender constraint exists.

Logging secrets for forensics

Investigation requires correlation identifiers—not raw bearer tokens, private keys, or unnecessary sensitive payloads.

API Replay Attack Prevention Checklist

  • Use HTTPS for all protected API traffic.
  • Define what must be fresh and what must be unique for every high-value operation.
  • Use a signed timestamp or equivalent creation/expiration semantics.
  • Use a nonce, proof ID, request ID, jti, event ID, or equivalent where single use is required.
  • Retain replay state for the complete proof-validity window.
  • Make replay state work across the actual cluster, region, or gateway topology.
  • Cryptographically bind the proof to enough request context.
  • Use audience restriction and sender-constrained OAuth tokens for high-value cases where practical.
  • Rotate or sender-constrain public-client refresh tokens.
  • Use idempotency or transaction state for retryable state changes.
  • Verify webhook signatures and provider-specific delivery/freshness semantics.
  • Keep one-time workflows stateful enough to invalidate spent artifacts.
  • Test exact replay, retry behavior, expiration, and cross-replica handling in an authorized environment.
  • Log correlation identifiers without logging reusable secrets.
  • Use runtime detection for replay-like behavior that exact cryptographic controls cannot see.

Primary References

Frequently Asked Questions

What is an API replay attack?

It is the reuse of previously valid API material so the server accepts it again. The reused material may be a signed request, token, JWT, webhook, authorization message, or business transaction.

Do timestamps alone prevent replay attacks?

No. They reduce the useful lifetime of captured material, but the same proof can still be reused inside the accepted window unless the server also detects reuse or the protocol has equivalent single-use semantics.

How do nonces prevent replay?

A nonce creates a per-message unique value. Replay resistance requires the nonce to be protected appropriately and the verifier to remember accepted values for the relevant validity window so duplicates can be rejected.

Can JWTs be replayed?

Yes. A valid JWT can normally be reused until it expires unless the application adds sender binding, one-time state, or another replay policy. RFC 7519 notes that the jti claim can be used for replay prevention, but the receiver has to enforce it.

How do DPoP and mTLS reduce token replay?

They sender-constrain OAuth tokens so possession of the token alone is insufficient. DPoP requires a request-specific proof from a private key; mTLS certificate-bound tokens require proof of possession of the key corresponding to the bound client certificate.

Is idempotency the same as replay protection?

No. Idempotency prevents duplicate business effects during safe retries. Replay protection determines whether a security proof or request should still be trusted. High-value APIs often need both.

How should webhook replay be handled?

Verify the provider signature, apply the provider's freshness rules, and deduplicate using stable event or delivery identifiers when the provider supplies them.

Where does Ammune fit?

Ammune can complement protocol controls with runtime visibility into repeated actions, sequences, request/response context, business behavior, and SIEM-ready evidence. It does not replace nonces, request signatures, sender-constrained tokens, replay caches, or idempotency.

Strengthen Replay Protection with Runtime API Visibility

Protocol controls should reject stale or reused proofs. Runtime API security adds context for repeated intent, abnormal sequences, credential misuse, and business-logic abuse that may use fresh outer requests.

Ammune Security · API Security Guide · Updated September 16, 2026