Skip to content

Return 401 for unverified webhook requests instead of 404 - #215

Merged
tobie merged 1 commit into
mainfrom
claude/practical-franklin-wun7xr
Sep 24, 2026
Merged

tobie merged 1 commit into
mainfrom
claude/practical-franklin-wun7xr

Conversation

@tobie

@tobie tobie commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Changed the webhook request verification flow to return HTTP 401 (Unauthorized) for unverified requests in production, instead of falling through to Express's default 404 handler. This provides clearer feedback to GitHub about authentication failures.

Key Changes

  • GitHub webhook endpoint (/github-hook):

    • Removed next parameter from route handler since it's no longer called
    • Added explicit res.sendStatus(401) response for unverified requests in production
    • Removed the next() call that was allowing unverified requests to fall through
  • Config endpoint (/config):

    • Removed next parameter from async route handler
    • Removed unnecessary finally block that was calling next()
  • Documentation (error-handling.md):

    • Updated to reflect that unverified requests now receive a 401 response instead of falling through to 404
    • Clarified that mismatched secrets will now show up as 401 in GitHub's delivery log
  • Tests (test/server.js):

    • Updated test expectations from 404 to 401 for both wrong signature and missing signature scenarios

Implementation Details

The changes eliminate unnecessary use of the next() callback in Express middleware. Since these endpoints don't need to pass control to subsequent middleware, removing the next parameter and explicit calls simplifies the code. The explicit 401 response for unverified webhooks provides better HTTP semantics and clearer debugging information in GitHub's webhook delivery logs.

https://claude.ai/code/session_01Qq8TZHcEcvGppVjWSdt7ek

…lying

An unverified request to /github-hook fell through to Express's 404,
which reads as a wrong URL in GitHub's delivery log rather than a
signature mismatch. Answer it with a 401 instead.

Both /github-hook and /config also called next() after sending their
response. With no later route, that landed in finalhandler, which finds
the headers already sent and destroys the socket. Neither handler needs
next(), so drop it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qq8TZHcEcvGppVjWSdt7ek
@tobie
tobie merged commit 778b2d6 into main Sep 24, 2026
1 check passed
@tobie
tobie deleted the claude/practical-franklin-wun7xr branch September 24, 2026 20:00
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.

2 participants