Describe the bug
In gateway/webhook/webhook.go, the RequestHandler looks up the per-source request channel from a map, then sends to it. If the source type has not been registered yet, the map lookup returns a nil channel, and sending to a nil channel blocks forever — the HTTP handler goroutine never returns and the response is never written.
This is a denial-of-service vulnerability: a single webhook request for an unregistered source type permanently consumes a goroutine and leaves the client hanging.
Code reference
gateway/webhook/webhook.go:233-238:
webhook.requestQMu.RLock()
requestQ := webhook.requestQ[sourceDefName] // nil if sourceDefName not in map
requestQ <- &req // BLOCKS FOREVER on nil channel!
webhook.requestQMu.RUnlock()
This happens when webhookV2HandlerEnabled is false (default in setup.go:80). In this mode, source types are registered lazily via processBackendConfig (handle_lifecycle.go:350-353) when backend config is received. If a webhook request arrives:
- Before backend config is processed (startup race)
- For a source type not present in the backend config
…the map lookup returns nil.
Steps to reproduce
- Configure a webhook source but delay backend config delivery
- Send a POST request to the webhook endpoint
- The request never returns — the handler is stuck on
requestQ <- &req (nil channel)
Expected behavior
The handler should verify the channel exists before sending:
requestQ, ok := webhook.requestQ[sourceDefName]
if !ok {
webhook.failRequest(w, r, "invalid webhook source", http.StatusNotFound)
webhook.ackCount.Add(1)
return
}
requestQ <- &req
Or alternatively, Register should be called unconditionally before the map lookup (removing the if webhook.config.webhookV2HandlerEnabled guard at line 233).
Describe the bug
In
gateway/webhook/webhook.go, theRequestHandlerlooks up the per-source request channel from a map, then sends to it. If the source type has not been registered yet, the map lookup returns a nil channel, and sending to a nil channel blocks forever — the HTTP handler goroutine never returns and the response is never written.This is a denial-of-service vulnerability: a single webhook request for an unregistered source type permanently consumes a goroutine and leaves the client hanging.
Code reference
gateway/webhook/webhook.go:233-238:This happens when
webhookV2HandlerEnabledisfalse(default insetup.go:80). In this mode, source types are registered lazily viaprocessBackendConfig(handle_lifecycle.go:350-353) when backend config is received. If a webhook request arrives:…the map lookup returns
nil.Steps to reproduce
requestQ <- &req(nil channel)Expected behavior
The handler should verify the channel exists before sending:
Or alternatively,
Registershould be called unconditionally before the map lookup (removing theif webhook.config.webhookV2HandlerEnabledguard at line 233).