Skip to content

feat(security): verify inbound webhook signatures#275

Open
220nightmore-spec wants to merge 1 commit into
Creditra:mainfrom
220nightmore-spec:feature/webhook-signature-verification-181
Open

feat(security): verify inbound webhook signatures#275
220nightmore-spec wants to merge 1 commit into
Creditra:mainfrom
220nightmore-spec:feature/webhook-signature-verification-181

Conversation

@220nightmore-spec

Copy link
Copy Markdown

Closes #181.

Summary

  • add inbound webhook signature verification middleware for X-Signature, X-Timestamp, and X-Nonce
  • sign and verify timestamp.nonce.raw_body with HMAC-SHA256 and constant-time comparison
  • reject missing/malformed signatures, stale timestamps, invalid HMACs, and replayed nonces
  • capture the raw JSON body through the Express parser verify hook so signatures are checked against the exact request bytes
  • add POST /api/inbound-webhooks/events as the signed ingestion endpoint
  • add an inbound nonce migration and in-process TTL nonce store
  • document partner signing requirements in docs/inbound-webhooks.md and update src/openapi.yaml

Security notes

  • requests fail closed with 503 if INBOUND_WEBHOOK_SECRET is not configured
  • the default timestamp tolerance is 5 minutes and can be configured with INBOUND_WEBHOOK_TIMESTAMP_TOLERANCE_MS
  • nonces are claimed only after signature and timestamp verification succeed

Validation

  • vitest run src/middleware/__tests__/inboundWebhookSignature.test.ts src/routes/__tests__/inboundWebhooks.test.ts src/db/migrations.test.ts src/db/validate-schema.test.ts --pool=forks --maxWorkers=1 (38 passed)
  • eslint src/middleware/rawBody.ts src/middleware/inboundWebhookSignature.ts src/middleware/__tests__/inboundWebhookSignature.test.ts src/services/inboundWebhookNonceStore.ts src/routes/inboundWebhooks.ts src/routes/__tests__/inboundWebhooks.test.ts src/index.ts
  • node --input-type=module -e "import fs from 'node:fs'; import yaml from 'yaml'; yaml.parse(fs.readFileSync('src/openapi.yaml', 'utf8')); console.log('OpenAPI spec valid');"
  • git diff --check
  • tsc --noEmit --pretty false still fails on existing unrelated main-branch errors in src/app.ts, src/container/Container.ts, src/middleware/requestLogger.ts, src/routes/credit*.ts, src/routes/dashboard.ts, src/routes/simulation.ts, and src/services/drawWebhookService.ts; no inbound webhook files are reported.

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.

Backend: Add webhook signature verification and replay protection for inbound webhooks

1 participant