Skip to content

[Security] Verify GitHub webhook signatures and rate-limit /github-webhook - #178

Merged
N-thnI merged 2 commits into
Vero-protocol:mainfrom
jahswillb-dev:security/webhook-hmac-verification
Jul 28, 2026
Merged

[Security] Verify GitHub webhook signatures and rate-limit /github-webhook#178
N-thnI merged 2 commits into
Vero-protocol:mainfrom
jahswillb-dev:security/webhook-hmac-verification

Conversation

@jahswillb-dev

@jahswillb-dev jahswillb-dev commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • /github-webhook accepted any JSON body shaped like a merged-PR event with no authentication and no rate limiting — confirmed via the repro in the issue (unsigned request returned 200 { registered: true }).
  • Add HMAC-SHA256 verification of X-Hub-Signature-256 (raw body captured via express.json({ verify }), compared with crypto.timingSafeEqual) — returns 401 on missing/invalid signature before any body-derived logic or registerTaskOnChain call runs.
  • Add express-rate-limit scoped to /github-webhook — returns 429 once the configured threshold is exceeded.
  • Document GITHUB_WEBHOOK_SECRET in .env.example and the README's Environment Variables table; update the Webhook Relayer docs, diagrams, and API reference; check off both README Deployment Checklist items.
  • scripts/mock-webhook.js now signs its payload with GITHUB_WEBHOOK_SECRET so local simulation exercises the real verification path.

Acceptance criteria

  • AC-1: missing/invalid X-Hub-Signature-256401, registerTaskOnChain never invoked ✅ (tested)
  • AC-2: requests exceeding the configured rate → 429 ✅ (tested)
  • AC-3: GITHUB_WEBHOOK_SECRET documented in .env.example and README env table ✅

Test plan

  • npx jest __tests__/webhook.test.js — 5 new tests (missing signature, invalid signature, wrong-secret signature, valid signature succeeds, rate-limit 429)
  • npx eslint index.js __tests__/webhook.test.js scripts/mock-webhook.js — clean
  • Manually re-ran the issue's exact curl repro against the running relayer — now returns 401 instead of 200 { registered: true }; a correctly signed request still returns 200

Closes #155

jahswillb-dev and others added 2 commits July 28, 2026 13:07
The relayer accepted any JSON body shaped like a merged-PR event with no
auth and no throttling, so a spoofed request could trigger on-chain
registration once real signing is wired up. Add HMAC-SHA256 verification
of X-Hub-Signature-256 (401 on missing/invalid, checked before any
body-derived logic) and express-rate-limit on the route (429 over quota).
Document GITHUB_WEBHOOK_SECRET and check off both README deployment
checklist items.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@N-thnI
N-thnI merged commit 6bc549c into Vero-protocol:main Jul 28, 2026
3 checks 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.

[Security] Relayer /github-webhook accepts unauthenticated requests — no signature verification or rate limiting

2 participants