Skip to content

fix(gateway/webhook): return 404 for unregistered source instead of blocking on nil channel (#6999) - #7161

Open
kotwal-itpro wants to merge 1 commit into
rudderlabs:masterfrom
kotwal-itpro:fix/webhook-nil-channel-dos-6999
Open

fix(gateway/webhook): return 404 for unregistered source instead of blocking on nil channel (#6999)#7161
kotwal-itpro wants to merge 1 commit into
rudderlabs:masterfrom
kotwal-itpro:fix/webhook-nil-channel-dos-6999

Conversation

@kotwal-itpro

Copy link
Copy Markdown

Fixes #6999.

Problem

RequestHandler looked up the per-source request channel from webhook.requestQ and immediately sent on it. When the source type had not been Register()ed — a condition that can occur when webhookV2 is disabled and the lazy registration in processBackendConfig has not yet run for a given source, or when a request arrives for a source type this instance does not handle — the map lookup returned a nil channel and the send blocked forever. The HTTP handler goroutine never returned, the client hung, and a goroutine leaked per unregistered request. This is the DoS described in #6999.

Fix

  • Comma-ok the map lookup at gateway/webhook/webhook.go:228.
  • Release the read lock before writing the response (existing lock discipline preserved for the success path).
  • Fail fast with the existing response.InvalidWebhookSource → HTTP 404 mapping (already defined in gateway/response).

Test

Adds TestWebhookRequestHandlerReturns404WhenSourceNotRegistered which:

  • Disables webhookV2HandlerEnabled (the pre-condition under which the bug reproduces on current HEAD).
  • Deliberately omits Register().
  • Sends the request in a goroutine guarded by a 2-second time.After so the test fails hard (rather than hanging) if the handler ever regresses back to blocking on nil channel.
  • Asserts http.StatusNotFound and body contains response.InvalidWebhookSource.

Passes under go test -race ./gateway/webhook/.... Full webhook test suite still passes.

…locking on nil channel (rudderlabs#6999)

RequestHandler used to fetch the per-source request channel from webhook.requestQ
and immediately send on it. When the source type had not been registered — a
condition that can occur when webhookV2 is disabled and the lazy registration
in processBackendConfig has not yet run for a given source, or when a request
arrives for a source type this instance does not handle — the map lookup
returns a nil channel and the send blocks forever. The HTTP handler goroutine
never returns, the client hangs, and a goroutine is leaked per unregistered
request. That is a straightforward DoS.

Comma-ok the map lookup, release the read lock before writing the response,
and fail fast with the existing response.InvalidWebhookSource / 404 mapping.

Adds a regression test that omits Register() and asserts the handler returns
StatusNotFound within 2s (rather than blocking indefinitely). Runs cleanly
under -race.

Fixes rudderlabs#6999
@contributor-support

Copy link
Copy Markdown

Thank you @kotwal-itpro for contributing this PR.
Please sign the Contributor License Agreement (CLA) before merging.

@github-actions

Copy link
Copy Markdown
Contributor

This PR is considered to be stale. It has been open 20 days with no further activity thus it is going to be closed in 7 days. To avoid such a case please consider removing the stale label manually or add a comment to the PR.

@github-actions github-actions Bot added the Stale label Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: nil channel send in webhook RequestHandler blocks HTTP handler forever (DoS)

1 participant