Skip to content

EventListener: Add request body size limit to prevent OOM from large payloads #2021

Description

@vdemeester

Summary

The EventListener reads the entire request body into memory with no size limit via io.ReadAll(request.Body) at two call sites:

  • pkg/sink/sink.go:153
  • pkg/sink/validate_payload.go:29

An attacker (or misbehaving webhook sender) streaming large payloads can exhaust the pod's memory, causing OOM kills. With memory limits set (standard for production), sustained large requests can keep the pod in CrashLoopBackOff.

The existing ReadTimeout (default 5s) does not mitigate this — in-cluster, data arrives fast enough to OOM the pod well within the timeout window.

Proposed Fix

Replace bare io.ReadAll with http.MaxBytesReader at both call sites, with a default cap of 3 MiB. This:

  • Rejects oversized requests with 413 Request Entity Too Large
  • Closes the connection immediately rather than draining the stream

3 MiB provides ample headroom — typical webhook payloads from GitHub, GitLab, and Bitbucket are 5–100 KB; the largest observed are ~1 MB.

The limit should be configurable via an EventListener flag (e.g. --el-max-body-size).

Example

// Before
event, err := io.ReadAll(request.Body)

// After
request.Body = http.MaxBytesReader(response, request.Body, maxBodySize)
event, err := io.ReadAll(request.Body)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions