MAX_MESSAGE_SIZE bounds only the first JSON value read, not the request body #250

Closed
opened 2026-11-03 07:52:13 +01:00 by clawbot · 1 comment
Collaborator

HandleCreateSession and HandlePostMessage in internal/handlers/api.go and HandleLogin in internal/handlers/auth.go wrap the body in http.MaxBytesReader with MAX_MESSAGE_SIZE and then call json.NewDecoder(body).Decode(&payload). Decode stops after the first JSON value. The rest of the body is never read, so the limit never fires on it, and nothing checks for trailing data.

Example: POST /api/v1/session with {"nick":"alice"} followed by 100 KiB of spaces, or of anything else, is accepted with 201. README.md says a body larger than MAX_MESSAGE_SIZE bytes gets 400 invalid request body. That holds only when the first JSON value itself does not end within the limit.

Definition of done:

  • On all three endpoints, a body larger than MAX_MESSAGE_SIZE bytes gets 400 invalid request body, whether or not its first JSON value ends within the limit.
  • Trailing bytes after the JSON value, other than whitespace, get the same 400 (reading the whole limited body and calling json.Unmarshal gives both for free).
  • One test per endpoint sends a small valid value followed by bytes past the limit and asserts 400.
  • make check is green. README.md needs no change.

Found during the fresh read of README.md for #190.

Model: fable-5-1

`HandleCreateSession` and `HandlePostMessage` in `internal/handlers/api.go` and `HandleLogin` in `internal/handlers/auth.go` wrap the body in `http.MaxBytesReader` with `MAX_MESSAGE_SIZE` and then call `json.NewDecoder(body).Decode(&payload)`. `Decode` stops after the first JSON value. The rest of the body is never read, so the limit never fires on it, and nothing checks for trailing data. Example: `POST /api/v1/session` with `{"nick":"alice"}` followed by 100 KiB of spaces, or of anything else, is accepted with `201`. `README.md` says a body larger than `MAX_MESSAGE_SIZE` bytes gets `400` `invalid request body`. That holds only when the first JSON value itself does not end within the limit. Definition of done: - On all three endpoints, a body larger than `MAX_MESSAGE_SIZE` bytes gets `400` `invalid request body`, whether or not its first JSON value ends within the limit. - Trailing bytes after the JSON value, other than whitespace, get the same `400` (reading the whole limited body and calling `json.Unmarshal` gives both for free). - One test per endpoint sends a small valid value followed by bytes past the limit and asserts `400`. - `make check` is green. `README.md` needs no change. Found during the fresh read of `README.md` for https://git.eeqj.de/sneak/neoirc/issues/190. Model: fable-5-1
Author
Collaborator

Built in #253: all three endpoints now read the whole limited body and decode it with json.Unmarshal. Posting a message without a valid session still gets 401, and logging in over the rate limit still gets 429, whatever the body size.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/neoirc/pulls/253: all three endpoints now read the whole limited body and decode it with `json.Unmarshal`. Posting a message without a valid session still gets `401`, and logging in over the rate limit still gets `429`, whatever the body size. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/neoirc#250