Reject NUL bytes before event persistence - #4700
Open
lenardhuebner88-rgb wants to merge 1 commit into
Open
Conversation
An event whose `content` or any tag value contains a NUL byte (0x00)
passes the full ingest validation and only fails inside Postgres:
invalid byte sequence for encoding "UTF8": 0x00
The relay maps that database error onto a bare HTTP 500, so a plain
client-side input problem is reported as an internal server error with
no usable body. Reproduced with a 38-byte message; content length is
irrelevant.
Reject NUL in `event.content` and in every tag value in
`ingest_event_inner`, before any database access, as
`IngestError::Rejected` — which the `/events` bridge already maps to
400 Bad Request. The CLI rejects the same input locally before signing
and names the byte offset, so users get an actionable message instead
of a relay round-trip.
Signed-off-by: Codex Sol <codex@buzz.local>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
An event whose
content— or any tag value — contains a NUL byte (0x00) passes the full ingest validation and only fails inside Postgres:The relay maps that database error onto a bare HTTP 500, so a plain client-side input problem is reported as an internal server error with no usable body. Reproduced with a 38-byte message — content length is irrelevant. It surfaced in practice when a client pasted text carrying a stray NUL: four sends failed in a row with
relay error 500: internal server errorand nothing actionable on the client side.Change
crates/buzz-relay/src/handlers/ingest.rs—ingest_event_innerrejects NUL inevent.contentand in every tag value, right after the existing content-size check and before any database access, asIngestError::Rejected. The/eventsbridge already mapsRejectedto400 Bad Request(crates/buzz-relay/src/api/bridge.rs), so no mapper change was needed.crates/buzz-cli/src/commands/messages.rs—cmd_send_messagerejects the same input locally, before signing, and names the byte offset. No silent stripping: the content is the user's, so it is refused rather than altered.Only
0x00is rejected. Other control characters are valid UTF-8 and Postgres accepts them, so widening the rule would reject content that works today.Tests
event_text_validation_rejects_nul_in_contentevent_text_validation_rejects_nul_in_tag_valueevent_text_validation_accepts_same_event_without_nul(positive control)send_message_rejects_nul_locally_with_byte_offsetcargo test -p buzz-cli→ 318 passed, 1 ignored, exit 0.cargo test -p buzz-relay event_text_validation→ 3 passed, exit 0. No existing test was modified.