@nodezor/webhook-shield
v0.0.1
Published
HMAC signature verification, replay attack prevention and idempotency guard for webhooks
Maintainers
Readme
@nodezor/webhook-shield
HMAC signature verification, timestamp replay prevention, and idempotency guard for inbound webhooks.
The Problem
Inbound webhooks from third-party services (Stripe, GitHub, Shopify) are vulnerable to HMAC signature spoofing, replay attacks, and duplicate event delivery. Developers often fail to implement proper idempotency checks, event deduplication, and reliable retry handling, leading to duplicated database operations or dropped webhook events.
Features
- 🔑 SHA-256 HMAC Verification: Uses
crypto.timingSafeEqualto prevent timing attacks. - ⏱️ Replay Attack Prevention: Validates webhook timestamps against configurable tolerance windows.
- ♻️ Idempotency Store: Deduplicates event IDs to prevent double processing.
- ⚡ Zero External Dependencies: Powered by Node.js native
crypto.
Installation
# pnpm
pnpm add @nodezor/webhook-shield
# npm
npm install @nodezor/webhook-shield
# yarn
yarn add @nodezor/webhook-shieldQuick Start / Usage Example
import { verifyWebhookSignature, createIdempotencyStore } from '@nodezor/webhook-shield';
const idempotency = createIdempotencyStore();
function handleWebhookRequest(payload: string, signature: string, eventId: string, timestamp: number) {
// 1. Check idempotency
if (idempotency.isDuplicate(eventId)) {
return { status: 200, message: 'Event already processed' };
}
// 2. Verify HMAC Signature and Timestamp Tolerance
const verification = verifyWebhookSignature({
secret: process.env.WEBHOOK_SECRET!,
signature,
payload,
timestamp,
toleranceSeconds: 300,
});
if (!verification.valid) {
throw new Error(`Unauthorized Webhook: ${verification.reason}`);
}
// 3. Mark processed
idempotency.record(eventId);
return { status: 200, message: 'Processed successfully' };
}API Reference
verifyWebhookSignature(options: WebhookVerificationOptions): WebhookVerificationResult
Verifies payload HMAC signature and timestamp tolerance.
| Option | Type | Description |
| :--- | :--- | :--- |
| secret | string | Secret signing key |
| signature | string | Received HMAC signature header |
| payload | string \| Record<string, unknown> | Raw body payload |
| toleranceSeconds | number | Max timestamp difference (default: 300s) |
| timestamp | number | Optional header timestamp |
computeHmacSignature(payload: string, secret: string): string
Computes SHA-256 HMAC signature.
createIdempotencyStore(ttlMs?: number)
Creates stateful event deduplication store (isDuplicate, record, clear).
License
MIT © PRX2112
