Skip to content

feat(verify): add the x-hub-signature verifier - #27

Merged
TheGreatAxios merged 1 commit into
mainfrom
x-hub-signature
Oct 15, 2026
Merged

TheGreatAxios merged 1 commit into
mainfrom
x-hub-signature

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Adds verify: "x-hub-signature": SHA-256 HMAC over the raw body compared in constant time against sha256=<hex>, with the signature, event and delivery header names taken from metadata.webhook.headers. Replay is keyed on the delivery id in the existing replay table for 24 hours and released on a failed delivery. The mail text is {"event","deliveryId","payload"}. A missing header or a non-JSON body answers 400. README documents the verifier, the headers field and the GitHub and Bitbucket Data Center header names.

Verification: bun run check (typecheck, lint, format, tests): 54 pass, 0 fail.

@TheGreatAxios TheGreatAxios left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review · Comment

Adds an x-hub-signature verifier: hex HMAC-SHA256 of the raw body against sha256=<hex>, header names from metadata.webhook.headers, delivery id as a 24h replay nonce, mail wrapped as {event, deliveryId, payload}.

Findings

  • src/resolve.ts:71 — header names are only trimmed, not checked as valid header tokens. A typo such as "x-github event" makes Headers.get throw (Invalid header name: 'x github event' under Bun) at src/hooks.ts:89, so every request to that hook ends in an unhandled 500 instead of the documented 404 for a misconfigured credential. Could parseHookHeaders reject names that fail /^[!#$%&'*+.^_|~0-9A-Za-z-]+$/` so the credential matches no hook, like a missing verifier?
  • README.md:69 — "the key stays held until it expires with its timestamp window" now also covers X-Hub-Signature keys, which have no timestamp and stay held for 24 hours. Worth saying so, since a GitHub manual redelivery after a crash gets 409 for a day.

Notes

  • PR body has no Closes <issue id> line, which CONTRIBUTING asks for.
  • No version bump in the branch, consistent with manual releases; this is additive, so the next release is a patch.

@TheGreatAxios
TheGreatAxios merged commit 21d1b1f into main Oct 15, 2026
2 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.

1 participant