Skip to content

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

Description

@RockyOmvi

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:

  1. Before backend config is processed (startup race)
  2. For a source type not present in the backend config

…the map lookup returns nil.

Steps to reproduce

  1. Configure a webhook source but delay backend config delivery
  2. Send a POST request to the webhook endpoint
  3. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions