npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

iph-replay-guard

v1.0.3

Published

A lightweight reusable Express.js middleware for protecting APIs against replay attacks using nonce and timestamp validation.

Readme

iph-replay-guard

A lightweight reusable Express.js middleware for protecting APIs against replay attacks using nonce and timestamp validation.


Overview

iph-replay-guard is an Express middleware package designed to prevent replay attacks in APIs and secure communication systems.

The middleware validates:

  • request nonce values
  • request timestamps
  • duplicate request reuse within a configurable time window

It is especially useful for:

  • signed APIs
  • encrypted payload APIs
  • payment systems
  • webhook protection
  • mobile applications
  • device-authenticated APIs

What Is a Replay Attack?

A replay attack occurs when an attacker captures a valid request and resends it later to repeat an action.

Examples:

  • duplicate payment requests
  • repeated transaction submissions
  • replayed authenticated API calls
  • reused signed requests

Replay attacks can occur even when requests are encrypted or signed.


How iph-replay-guard Works

The middleware validates three things:

  1. a nonce header
  2. a timestamp header
  3. whether the nonce was already used

If:

  • the timestamp is too old
  • the nonce already exists
  • required headers are missing

the request is blocked.


Features

Replay Protection

Blocks duplicate requests using unique nonce tracking.


Timestamp Validation

Rejects requests outside an allowed time window.


Pluggable Nonce Storage

Supports:

  • memory storage
  • Redis
  • databases
  • custom distributed stores

Route Skipping

Supports:

  • custom skip functions
  • multiple skipped paths

Lightweight

Minimal runtime overhead and easy Express integration.


Installation

npm install iph-replay-guard

Basic Usage

import express from "express";

import {
  createMemoryNonceStore,
  createReplayProtection,
} from "iph-replay-guard";

const app = express();

const store = createMemoryNonceStore();

app.use(
  createReplayProtection({
    store,
  }),
);

Request Requirements

Clients must send:

  • x-nonce
  • x-timestamp

Example Request

POST /api/orders

x-nonce: 8d95a83f-4f22-42c8-a1de-2c83f34e749e
x-timestamp: 1770000000000

How Nonces Work

A nonce is a unique value generated for every request.

Rules:

  • must be unique per request
  • should never repeat
  • typically generated using UUIDs

Example:

8d95a83f-4f22-42c8-a1de-2c83f34e749e

Middleware Order

Recommended middleware order:

app.use(express.json());

app.use(replayProtection);

app.use(routes);

Place replay protection:

  • before protected routes
  • before request decryption logic
  • before sensitive business logic

API

createReplayProtection(options)

Creates and returns the replay-protection middleware.


createMemoryNonceStore()

Creates a simple in-memory nonce store.

Recommended only for:

  • local development
  • testing
  • single-instance applications

Type Definitions

export type NonceStore = {
  hasSeen(nonce: string): Promise<boolean>;

  mark(
    nonce: string,
    expiresAt: Date,
  ): Promise<boolean>;
};

export type ReplayProtectionOptions = {
  skip?: (req: Request) => boolean;

  skipPaths?: string[];

  timestampHeader?: string;

  nonceHeader?: string;

  maxAgeSeconds?: number;

  store: NonceStore;
};

Options

store

Type:

NonceStore

Required nonce storage implementation.

The store is responsible for:

  • checking whether a nonce exists
  • storing new nonces
  • handling expiration

skip

Type:

(req: Request) => boolean

Custom logic for skipping replay protection.

Example:

createReplayProtection({
  store,

  skip: (req) =>
    req.method === "GET",
});

skipPaths

Type:

string[]

List of paths excluded from replay protection.

Example:

createReplayProtection({
  store,

  skipPaths: [
    "/health",
    "/metrics",
    "/api/payments/webhook",
  ],
});

timestampHeader

Type:

string

Timestamp header name.

Default:

x-timestamp

nonceHeader

Type:

string

Nonce header name.

Default:

x-nonce

maxAgeSeconds

Type:

number

Maximum allowed request age.

Default:

300

(5 minutes)


Multiple Route Skipping Example

app.use(
  createReplayProtection({
    store,

    skipPaths: [
      "/health",
      "/metrics",
      "/api/payments/webhook",
    ],
  }),
);

Conditional Skipping Example

app.use(
  createReplayProtection({
    store,

    skip: (req) =>
      req.method === "GET" ||
      req.path.startsWith("/public"),
  }),
);

Custom Nonce Store Example

const store = {
  async hasSeen(nonce: string) {
    return false;
  },

  async mark(
    nonce: string,
    expiresAt: Date,
  ) {
    return true;
  },
};

app.use(
  createReplayProtection({
    store,
  }),
);

Redis Store Example

const store = {
  async hasSeen(nonce: string) {
    return Boolean(
      await redis.get(nonce),
    );
  },

  async mark(
    nonce: string,
    expiresAt: Date,
  ) {
    const ttlSeconds =
      Math.ceil(
        (
          expiresAt.getTime() -
          Date.now()
        ) / 1000,
      );

    await redis.set(
      nonce,
      "1",
      "EX",
      ttlSeconds,
    );

    return true;
  },
};

Response Status Codes

| Status | Meaning | | ------ | ---------------------------- | | 400 | Missing replay headers | | 408 | Timestamp expired | | 409 | Replay request detected | | 500 | Internal nonce-store failure |


Example Error Responses

Missing Headers

{
  "success": false,
  "message": "Missing replay protection headers"
}

Expired Timestamp

{
  "success": false,
  "message": "Request timestamp outside allowable window"
}

Replay Detected

{
  "success": false,
  "message": "Replay request detected"
}

Internal Flow

The middleware performs the following steps:

  1. checks skipped routes
  2. reads nonce header
  3. reads timestamp header
  4. validates request age
  5. checks nonce existence
  6. stores nonce
  7. forwards request

Security Recommendations

Use HTTPS

Replay protection should always be used with HTTPS.

Without HTTPS:

  • attackers can intercept requests
  • headers can be captured
  • replay attacks become easier

Use Cryptographically Secure Nonces

Recommended:

  • UUID v4
  • crypto.randomUUID()
  • secure random generators

Avoid:

  • sequential IDs
  • timestamps alone
  • predictable strings

Use Distributed Storage

For production systems with multiple servers:

  • Redis
  • Memcached
  • distributed databases

Avoid memory stores in clustered deployments.


Performance Notes

The middleware is lightweight.

Operations performed:

  • header parsing
  • timestamp comparison
  • nonce lookup
  • nonce insertion

Performance depends mainly on the storage backend.


Best Practices

  • place middleware early in the request chain
  • combine with request signing
  • combine with payload encryption
  • use short replay windows
  • use distributed nonce storage
  • rotate secrets regularly

Recommended Security Stack

Recommended production setup:

HTTPS
↓
Replay Protection
↓
HMAC Verification
↓
Payload Decryption
↓
Authentication
↓
Application Routes

Limitations

Memory Store Limitations

The memory store:

  • is process-local
  • resets on restart
  • does not work across multiple servers

Clock Synchronization

Replay protection depends on timestamps.

Ensure:

  • servers use NTP
  • client clocks are reasonably accurate

Example Full Setup

import express from "express";

import {
  createMemoryNonceStore,
  createReplayProtection,
} from "iph-replay-guard";

const app = express();

const store = createMemoryNonceStore();

app.use(express.json());

app.use(
  createReplayProtection({
    store,

    maxAgeSeconds: 300,

    skipPaths: [
      "/health",
      "/api/payments/webhook",
    ],
  }),
);

app.listen(3000);

License

MIT


Author

Published by: Prashant Srivastav


Package

https://www.npmjs.com/package/iph-replay-guard