DEV Community

Keith Azodeh
Keith Azodeh

Posted on Originally published at Medium Fully Autonomous

GitHub Added Webhook IPs. Don’t Trust the Payload Yet.

GitHub’s October 29 update adds three webhook delivery ranges to the Meta API’s hooks field. Teams with static allowlists need to add them alongside existing ranges; teams already updating from that API need no change for these additions. It is a useful maintenance notice with an easy trap: an allowed network source does not replace verification of the request body. Keep the signature check after updating the firewall.

Disclosure: This article was generated and fact-checked with AI using the public sources linked here. It was published through an automated workflow and has not been reviewed by Keith.

The Okeike Web Editor case study describes a working editor under ongoing development. Its publishing path creates a GitHub commit and follows an existing deployment pipeline to the relevant Firebase Hosting target. A site registry and source-version controls keep edits bounded to the intended site and version.

That makes publishing notifications a useful design example. The receiver below is a proposed extension for a workflow like Okeike’s, not a claim about its current webhook implementation or an identified vulnerability. Imagine a notification that updates a release’s status in the editor. Before trusting it, the application needs to establish which request arrived, whether its body is authentic, and which release it can affect.

Let the network gate answer a narrow question

An allowlist answers whether a connection’s source is permitted by the network policy. It helps reduce unwanted traffic reaching the receiver. It does not tell the application that the JSON describes the right repository, site, or release.

Use the current hooks field from GitHub’s linked Meta API rather than treating this article as a permanent address list. Keep the range refresh procedure separate from the application’s webhook secret. Updating one should not require disabling the other.

In the proposed receiver, diagnostics would distinguish an ingress rejection from an application signature rejection. Otherwise, “the webhook failed” hides two different repairs. A delivery blocked before reaching the application cannot be fixed by changing its JSON parser.

Verify the body that actually arrived

GitHub’s delivery validation documentation specifies HMAC-SHA256 verification using the configured webhook secret and the payload contents, with the supplied signature in X-Hub-Signature-256. It recommends a constant-time comparison rather than ordinary string equality.

Preserve the original request body for this step. Parsing JSON and then serializing it again can change whitespace or representation while preserving the same apparent object. The signature concerns the received payload, not a newly formatted equivalent. Middleware, proxies, and body parsers belong in the verification review because they can change what the handler sees.

In this design, an absent or invalid signature stops processing before any publishing state changes. Parsing and interpreting the verified body come next. Keep the secret in server-side configuration, outside browser code and source control.

A useful negative test starts with a valid synthetic delivery, changes one body value, and keeps the original signature. The receiver should reject it even when the test harness represents its network source as allowed. That test demonstrates the separation between the two controls without sending hostile traffic to production.

Route the verified event to one permitted release

A valid signature is still not permission to update every site in a multi-site editor. The proposed handler should resolve the repository identity and relevant revision from the verified payload against its own configured site mapping. It should only apply event types and outcomes that the receiver was built to handle.

Do not let an arbitrary site name or destination URL select where a release update goes. A mismatched repository and revision should leave the unrelated site untouched. An authentic notification for another repository can be irrelevant to this receiver.

This is where a registry earns its maintenance cost. A deliberate mapping is more work than forwarding everything to a shared handler, but it gives the application a place to define which external facts may affect each local record. Tests can inspect that rule without depending on a model to interpret a message correctly.

Separate a new delivery from new work

GitHub’s webhook best practices recommend checking event types and actions and using X-GitHub-Delivery to track deliveries. A requested redelivery retains the original delivery ID.

For the proposed release-status receiver, repeated delivery should not create a second release or repeat an external side effect. Record delivery handling durably and make the release update idempotent around the repository, revision, and intended transition. A delivery-ID check is useful bookkeeping; it is not a substitute for authenticating the body or validating the transition.

Use a small fixture set before rollout: valid intended release, changed body with stale signature, missing signature, valid event for an unrelated repository, and a repeated delivery. Inspect the resulting records and queued work, not only the HTTP response. These are proposed acceptance checks, not reported Okeike test results.

GitHub’s new ranges help legitimate deliveries reach their destination. The receiver still has to earn the right to act: verify the body, map it to the intended release, and apply only the transition that belongs there.

Top comments (0)