Skip to content

fix(sources): cap decompressed body to prevent OOM#25488

Open
pront wants to merge 7 commits into
masterfrom
fix/http-source-decompression-bomb
Open

fix(sources): cap decompressed body to prevent OOM#25488
pront wants to merge 7 commits into
masterfrom
fix/http-source-decompression-bomb

Conversation

@pront
Copy link
Copy Markdown
Member

@pront pront commented May 22, 2026

Summary

decompress_body (shared by http_server, prometheus_remote_write, prometheus_pushgateway, heroku_logs, and the opentelemetry HTTP receiver) decoded gzip/deflate/zstd/snappy request bodies into an unbounded Vec. A single unauthenticated POST with a small compressed bomb could OOM-kill Vector in a fraction of a second.

This PR caps both the aggregated request body and decompressed payload at 100 MiB and returns HTTP 413 when exceeded. The raw-body cap is enforced while streaming the request body, so chunked or missing-Content-Length requests cannot bypass the limit. The cap is a constant for now; a follow-up can expose it as a config field if needed.

Vector configuration

No configuration changes.

How did you test this PR?

Unit tests in encoding.rs, including gzip/snappy/zstd/identity limit cases and bounded streaming body collection cases, plus an end-to-end test in http_server that streams a 200 MiB gzip bomb fixture without allocating the plaintext and asserts a 413 response.

Future work

  • Expose the cap as a per-source config field if any deployment needs to raise or lower it.

Change Type

  • Bug fix

Is this a breaking change?

  • Yes
  • No

Does this PR include user facing changes?

  • Yes. Please add a changelog fragment based on our guidelines.

The shared decompress_body helper used by http_server,
prometheus_remote_write, prometheus_pushgateway, heroku_logs, and the
opentelemetry HTTP receiver previously read the gzip/deflate/zstd/snappy
output into an unbounded Vec. A single unauthenticated POST with a small
compressed bomb could OOM-kill the Vector process.

Cap the decompressed payload at 100 MiB and return HTTP 413 when
exceeded. gzip/deflate/zstd are wrapped with io::Take; snappy is
rejected up front via snap::raw::decompress_len before allocating. Also
short-circuit at the warp layer when the declared Content-Length
already exceeds the cap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the domain: sources Anything related to the Vector's sources label May 22, 2026
pront and others added 3 commits May 22, 2026 14:36
decompress_body is pub, but DEFAULT_MAX_DECOMPRESSED_BODY_SIZE and
decompress_body_with_limit are pub(crate). The intra-doc link lint
fails CI under #![deny(warnings)] when public docs reference private
items. Inline the 100 MiB number in the doc comment instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@pront pront marked this pull request as ready for review May 26, 2026 14:44
@pront pront requested a review from a team as a code owner May 26, 2026 14:44
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d3730c100

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/sources/util/http/prelude.rs Outdated
Comment thread src/sources/util/http/encoding.rs
Comment thread src/sources/util/http/encoding.rs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: sources Anything related to the Vector's sources

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant