Skip to content

fix: prevent potential request body double-read in webhook handler#666

Open
itsmiso-ai wants to merge 1 commit into
mainfrom
foreman/wl-misospace-dispatch-656/issue-656
Open

fix: prevent potential request body double-read in webhook handler#666
itsmiso-ai wants to merge 1 commit into
mainfrom
foreman/wl-misospace-dispatch-656/issue-656

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

What

Moves request.arrayBuffer() to execute before authorizeRequest() in the PR follow-up webhook handler, and adds a test verifying body integrity when authorization consumes the stream.

Why

If authorizeRequest ever reads/consumes the request body, the subsequent…

Fixes #656

Opened by foreman on review GO (workload wl-misospace-dispatch-656).

Move the body read (request.arrayBuffer()) before calling authorizeRequest()
so that if authorizeRequest ever consumes the body stream, HMAC verification
still operates on the original payload rather than an empty buffer.

Also reset processPrFollowupEvents mock in beforeEach to prevent test
interference from the "returns 500 on processing error" test case.

Add regression test that verifies body integrity is preserved when the
request body is consumed before authorization.

Fixes #656

Signed-off-by: Saffron <[email protected]>
@itsmiso-ai
itsmiso-ai requested a review from joryirving as a code owner July 25, 2026 10:02

@its-saffron its-saffron Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AI Automated Review

Full PR review.

Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — routed smart (risk match: public_route_changes)

Recommendation: Approve

This PR correctly addresses the security concern in issue PR 656 by reordering the request body read to occur before authorizeRequest(). The change is minimal (4-line net change), targeted, and includes a regression test.

Change-by-Change Findings

src/app/api/pr-followup/webhook/route.ts

  • What changed: Moved request.arrayBuffer() to execute before authorizeRequest(), with a clarifying comment.
  • Security impact: Prevents a potential HMAC verification bypass where an empty body would silently pass signature verification if authorizeRequest ever consumed the request stream.
  • Behavior preserved: Authorization still returns 401 for unauthenticated requests; HMAC verification still occurs after auth.

src/app/api/pr-followup/webhook/route.test.ts

  • What changed: Added a regression test that clones the request, reads the body independently before calling POST, and verifies the body was not consumed.
  • Coverage: Tests the defensive posture—verifies the handler still works correctly even if authorization reads the stream.

Required Checks

✅ verify route access controls are in place

Confirmed. The authorizeRequest(request) call remains in place (line 193 in the diff) and still returns 401 when !auth.authorized. Authorization is unchanged—the fix only reorders when the body is read. No route-level security has been removed or weakened.

✅ check for unintended public endpoints

Confirmed. No new endpoints were added. The webhook route at /api/pr-followup/webhook remains the only modified route and continues to enforce bearer token authentication via authorizeRequest(). The webhook is an inbound GitHub webhook endpoint; it is not exposed as a public consumer-facing API beyond its existing GitHub webhook purpose.

Standards Compliance

  • API routes: Returns appropriate HTTP status codes (401 for unauthorized, 400 for missing headers).
  • Error handling: Uses errorResponse() pattern consistent with the codebase.
  • No commit of secrets: No secrets were introduced.
  • Auth consistency: Uses the established authorizeRequest helper from lib/auth.ts.

Linked Issue Fit

Issue PR 656 acceptance criteria:

  1. "Move the body read before authorization" — ✅ Done. request.arrayBuffer() now executes before authorizeRequest().
  2. "Add a test that verifies body integrity after authorization" — ✅ Done. Regression test added at line 199 of the test file.

The implementation fully satisfies the issue requirements.

CI Results

All checks passed: Build, Docker Build, Tests, Lint, Typecheck.

Findings

None.

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.

[P3] Prevent potential request body double-read in webhook handler

1 participant