Skip to content

fix(server): bound the pre-auth request-body read - #85

Open
0xKarm wants to merge 2 commits into
tempoxyz:mainfrom
0xKarm:fix/request-body-limit
Open

fix(server): bound the pre-auth request-body read#85
0xKarm wants to merge 2 commits into
tempoxyz:mainfrom
0xKarm:fix/request-body-limit

Conversation

@0xKarm

@0xKarm 0xKarm commented Jul 14, 2026

Copy link
Copy Markdown

Bound the pre-auth request-body read (ReadRequestBody)

Problem. ReadRequestBody calls io.ReadAll(r.Body) with no size limit, and
the charge middleware calls it on every request — before any credential is
checked — so it can compute/validate the body digest. Headers are already capped
at 16 KB (pkg/mpp/parse.go), but the body is not. An unauthenticated client
can POST arbitrarily large bodies to any protected route and force the server to
buffer each one in memory before it even returns the free 402. That's a
memory-exhaustion DoS reachable without holding a payment credential. The core
net/http path plus the Gin and Echo adapters all funnel through
ReadRequestBody and are affected; Fiber reads via c.Body() (fasthttp bounds
that itself) and is not.

Fix.

  • Add server.MaxRequestBodyBytes (default 1 MiB, 0 disables).
  • ReadRequestBody now reads through io.LimitReader(r.Body, limit+1) and
    returns an error when the body exceeds the limit, instead of buffering it all.
  • Callers already translate that error into ErrBadRequestHTTP 400, so no
    call-site changes are needed. The body is still fully restored for the handler
    when it's within bounds.

Compatibility. Default limit is generous (1 MiB) and tunable per deployment;
existing in-bounds requests behave exactly as before. Setting
MaxRequestBodyBytes = 0 restores the old unbounded behavior for anyone who
needs it.

Tests added (pkg/server/middleware_test.go):

  • TestReadRequestBodyEnforcesLimit — a body exactly at the limit is accepted
    and restored intact; one byte over is rejected with an exceeds error.
  • TestChargeMiddlewareRejectsOversizedBody — an oversized POST to a protected
    route returns 400 before verification runs.

go test ./pkg/server/ok.

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.

1 participant