Skip to content

Verify GitHub Webhook Signatures #32

@adarshm11

Description

@adarshm11

Summary

The /webhook endpoint currently accepts any incoming POST request without verifying its origin. GitHub signs every webhook payload using a shared secret and includes the signature in the X-Hub-Signature-256 header. We should validate this header to reject forged or unauthorized requests.

Problem

Any party that knows the webhook URL can send arbitrary payloads to trigger deployments. This is a security risk — a bad actor could craft a push event payload and cause the server to run git pull and docker compose up on any configured repo.

Proposed Solution

  1. Add a WEBHOOK_SECRET environment variable (set in .env).
  2. In the /webhook handler, compute HMAC-SHA256 of the raw request body using the secret.
  3. Compare against the X-Hub-Signature-256 header value using a constant-time comparison (hmac.compare_digest).
  4. Return 403 Forbidden if the signature is missing or does not match.
import hmac, hashlib

def verify_signature(payload: bytes, signature_header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Acceptance Criteria

  • WEBHOOK_SECRET is read from the environment on startup
  • Requests with a missing or invalid X-Hub-Signature-256 header return 403
  • Valid requests continue to be processed normally
  • README is updated with instructions for setting the webhook secret in GitHub and .env

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions