Skip to main content

Overview

In addition to HMAC signature verification, the EASYCRED API gateway enforces two additional security gates to prevent replay attacks and request tampering: Timestamp Drift and Nonce Replay protection.

Timestamp Drift Gate

The gateway compares the x-timestamp header value against the server’s current UTC time. If the difference exceeds ±300 seconds (5 minutes), the request is rejected:
| T_server - T_request | > 300 seconds  →  401 Unauthorized
Why this matters: Even if an attacker intercepts a valid signed request, they cannot re-send it more than 5 minutes later — the signature will be rejected as stale.

Valid Window

Requests with x-timestamp within ±300 seconds of server time are accepted.

Outside Window → 401

Requests older than 5 minutes or with future timestamps beyond 5 minutes are rejected.
Keep your server clock synchronized using NTP (Network Time Protocol). Clock drift is the most common cause of unexpected 401 errors in production.

Nonce Replay Gate

Every request must include a unique x-nonce value. The gateway stores all nonces seen within the drift window in a distributed Redis cache. If a request arrives with a nonce that has already been used within the window, it is immediately rejected:
Duplicate nonce within drift window  →  401 Replayed request rejected
Why this matters: Even within the 5-minute timestamp window, an attacker cannot replay an intercepted request because the nonce is already “used up”.

Nonce Requirements

RequirementDetails
FormatPrintable ASCII characters
Length1–200 characters
UniquenessMust be unique per request
RecommendedUUID v4 (e.g., 94fc6cee-137c-4206-bb0a-48623bd0847c)

Combined Protection Model

Both gates work together to provide layered security:
Incoming Request

      ├── ✓ Valid HMAC Signature?
      │         └── No → 401 Bad Signature

      ├── ✓ Timestamp within ±300s?
      │         └── No → 401 Stale Timestamp

      ├── ✓ Nonce not seen before?
      │         └── No → 401 Replayed Request

      └── ✓ All gates passed → Request processed

Troubleshooting

ErrorLikely CauseFix
401 Stale timestampServer clock driftSync clock with NTP
401 Replayed requestNonce reused across retriesGenerate a fresh UUID per request attempt
401 Bad signatureSigning string built incorrectlyVerify canonical string construction, especially the empty body "" for GET requests