fix: reject newline characters in SSE event and id fields by subhashdasyam · Pull Request #15187 · fastapi/fastapi
AI review requested due to automatic review settings
March 21, 2026 14:57`format_sse_event()` interpolated the `event` and `id` fields into SSE wire-format bytes without stripping or rejecting newline characters. A `\n` or `\r\n` in either field injects an additional SSE field-line into the stream — enabling event-type spoofing and fabricated data payloads in browser EventSource clients. The `data` and `comment` fields were already protected via `splitlines()`; the omission for `event` and `id` was an inconsistency, not a design decision. The identical bug class was fixed in Hono (GHSA-p6xx-57qc-3wxr). Changes: - Add `_check_event_no_newline()` validator and apply it to `ServerSentEvent.event` via `AfterValidator` - Extend `_check_id_no_null()` to also reject `\n` and `\r` - Strip `\r`/`\n` in `format_sse_event()` for `event` and `id` as defense-in-depth (low-level function, bypasses model validators) - Add 7 regression tests covering LF/CR rejection in both the model and the low-level formatting function Severity: Medium (client-side injection; server unaffected) CWE: CWE-116 — Improper Encoding for Output in a Different Plaintext Context OWASP: A03:2021 — Injection Prior art: Hono GHSA-p6xx-57qc-3wxr (same class, same fix pattern)
…'id' `_check_event_no_newline` lacked a `\0` check that `_check_id_no_null_or_newline` has had since the original implementation. Similarly, `format_sse_event()` stripped `\0` from `id` but not from `event`. Changes: - Extend `_check_event_no_newline` to also reject `\0` characters - Strip `\0` in `format_sse_event()` for `event` (mirrors existing `id` behavior) - Add `test_server_sent_event_null_event_rejected` regression test `event` and `id` are now fully symmetric in both the model validator and the low-level wire formatter.
…d chars Replace silent .replace() sanitization in format_sse_event() with explicit ValueError raises for \n, \r, and \0 in the event and id fields. Previously, format_sse_event() would strip those characters, creating a behavioral inconsistency with ServerSentEvent's AfterValidator which raises on the same input. As YuriiMotov pointed out: data allows newlines by SSE spec design (each line becomes a separate data: frame), but event and id are single-token fields where a newline is always a protocol violation. Silent stripping masks bugs at the call site; raising surfaces them where they belong. Both code paths now fail identically for the same invalid input. Tests updated from strip-behavior assertions to ValueError assertions, plus two new null-byte tests covering format_sse_event() directly for event and id.
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