Skip to content

fix(security): enforce max request body size to prevent memory exhaustion (CWE-400) - #13

Merged
oboard merged 2 commits into
oboard:mainfrom
I3eg1nner:fix/cwe400-body-size-limit
Aug 18, 2026
Merged

fix(security): enforce max request body size to prevent memory exhaustion (CWE-400)#13
oboard merged 2 commits into
oboard:mainfrom
I3eg1nner:fix/cwe400-body-size-limit

Conversation

@I3eg1nner

Copy link
Copy Markdown
Contributor

Vulnerability

The HTTP request handler reads the entire request body into memory with no size limit:

Native backend (mocket.native.mbt:385):

body_reader.read_all().binary()

JS backend (mocket.js.mbt:342-345):

let buffer = Buffer()
req.on("data", data => {
    buffer.write_bytes(node_body_chunk_to_bytes(data))
})

An unauthenticated attacker can send a single POST request with an arbitrarily large body, causing the server to allocate until OOM and crash. Tested with payloads up to 100MB — all accepted without rejection.

CVSS: 7.5 (High) — Network/Low/None/None (Availability)

Fix

Add a configurable max_body_size field to Mocket (default: 1MB):

  1. Native backend: Check Content-Length header upfront and enforce a streaming read limit via read_body_limited(); return 413 Request Entity Too Large when exceeded.
  2. JS backend: Track cumulative chunk size in the data callback and return 413 when the limit is crossed.

Users can customize via Mocket::new(max_body_size=5242880) (5MB) or disable with max_body_size=0.

Test Plan

  • Normal POST requests under 1MB are accepted
  • POST with >1MB body returns 413
  • max_body_size=0 disables the limit (backward compatible)
  • Existing test suite passes (49/49)
  • Builds on both native and js targets

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

…tion (CWE-400)

Add configurable `max_body_size` (default 1MB) to `Mocket` to reject oversized
HTTP request bodies before they are buffered into memory.

- Native backend: check Content-Length header upfront and enforce a streaming
  read limit via `read_body_limited()`; return 413 when exceeded.
- JS backend: track cumulative chunk size in the `data` callback and return 413
  when the limit is crossed.

Without this fix an unauthenticated attacker can send a single POST with an
arbitrarily large body, causing the server to allocate until OOM.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@I3eg1nner

Copy link
Copy Markdown
Contributor Author

Note: CI failures are pre-existing on the main branch (the last 3 main-branch pushes also failed with the same errors):

  1. typo-check: False positives from third-party mongoose.h/mongoose.c (e.g., wihwith, tolentoken)
  2. build (nightly): --deny-warn treats derive(Eq, Debug) deprecation warnings in uri/uri.mbt as errors
  3. moon info: pkg.generated.mbti drift between MoonBit toolchain versions

None of these are related to this PR's changes. The fix builds and tests clean on both native and js targets locally (49/49 tests pass).

@oboard
oboard merged commit 9024a99 into oboard:main Aug 18, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants