This site is not affiliated with or endorsed by Cloudflare, Inc. It simply showcases experiments built using Cloudflare services.
Cloudflare Experiments

Webhook Signature Verifier

Verify HMAC-SHA256 webhook signatures with timing-safe comparison at the edge

Accept a raw payload, secret, signature header value, and algorithm. Computes the expected HMAC (Stripe/GitHub sha256= hex style) and returns whether it matches using a timing-safe compare.

Features

  • POST /verify - HMAC-SHA256 verification with clear comparison explanation
  • Supports prefixed signatures (sha256=...) and raw hex
  • Uses Web Crypto at the edge; no external libraries

API Reference

POST /verify

payload string (required) - Raw request body as received.

secret string (required) - Shared signing secret.

signature string (required) - Signature from the webhook header.

algorithm string (optional) - Default sha256.

Example Request

curl -X POST "https://your-worker.workers.dev/verify" \
  -H "Content-Type: application/json" \
  -d '{"payload":"{\"id\":1}","secret":"whsec_test","signature":"sha256=..."}'

Success Response

{
  "match": true,
  "algorithm": "sha256",
  "expectedSignature": "sha256=...",
  "providedSignature": "sha256=...",
  "explanation": "Timing-safe comparison of 32-byte HMAC digests returned match."
}

Error Codes

  • 400 - INVALID_BODY, MISSING_FIELD, INVALID_ALGORITHM

Use Cases

  • Debug Stripe, GitHub, or Shopify webhook signature mismatches
  • Learn timing-safe HMAC verification patterns for Workers
  • Validate signing logic before wiring production webhook handlers

Limitations

  • HMAC-SHA256 only in this experiment
  • Secrets are sent in the request body; use only for debugging, not production traffic
  • No replay protection or timestamp validation

Deployment

Configure bindings

See wrangler.json and the experiment README for required bindings.

Test your deployment

See the experiment README for curl examples.

Local Development

cd apps/experiments/webhook-signature-verifier
npm install
npm run dev

Configuration

No bindings required beyond the Workers runtime.

Cloudflare Features Used

On this page