Skip to content

[#902] Add signed webhook replay protection - #911

Merged
greatest0fallt1me merged 2 commits into
Predictify-org:mainfrom
arisu6804:feat/issue-902-signed-webhook-replay-protection
Aug 27, 2026
Merged

[#902] Add signed webhook replay protection#911
greatest0fallt1me merged 2 commits into
Predictify-org:mainfrom
arisu6804:feat/issue-902-signed-webhook-replay-protection

Conversation

@arisu6804

Copy link
Copy Markdown
Contributor

Summary

Adds rotating, timestamped, nonce-bound webhook signatures while keeping the existing dispatcher API and legacy single-secret path compatible.

Security design

  • Signs the exact raw body plus a fixed domain, key id, timestamp, and nonce with HMAC-SHA256.
  • Uses a bounded key ring with activation and expiry windows so rotation can overlap safely.
  • Enforces timestamp tolerance before verification and atomically claims a nonce only after a valid constant-time signature comparison.
  • Rejects malformed, unknown-key, inactive-key, stale/future, replayed, and invalid-signature messages with stable internal reasons.
  • Persists timestamp/nonce headers with deliveries so retries reuse the same signed message.
  • Bounds nonce cache growth and exposes only non-secret key metadata.

Acceptance criteria

  • Valid rotation keys work only within their activation/expiry windows.
  • Old timestamps and reused nonces are rejected.
  • Signature comparison is constant-time and failure details are not exposed by the dispatcher helper.
  • Raw byte changes are rejected even when parsed JSON is equivalent.
  • Tests cover rotation overlap, timestamp boundaries, replay, malformed headers, tampering, TTL, bounded eviction, and retry reuse.

Verification

  • npx jest --runInBand --testMatch '**/src/services/signedWebhookSecurity.test.ts' '**/src/services/signedWebhookDispatcher.test.ts' — 17/17 passing
  • ESLint on all changed TypeScript files — passing

The repository-wide build is currently blocked by a pre-existing parse error in src/routes/users.ts (line 330), and Jest reports an existing open-handle warning after the focused suites complete. No generated OpenAPI changes or unrelated fixes are included.

Closes #902

@greatest0fallt1me
greatest0fallt1me merged commit 3f639ea into Predictify-org:main Aug 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GrantFox][High] Add signed webhook replay protection

2 participants