{"record":{"id":"da9fc46c36d3e74b","repo":"gofiber/fiber","slug":"errinvalidfield","errorCode":"errInvalidField","errorMessage":"field must not contain CR or LF","messagePattern":"field must not contain CR or LF","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/sse/event.go","lineNumber":15,"sourceCode":"package sse\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gofiber/utils/v2\"\n)\n\nvar errInvalidField = errors.New(\"field must not contain CR or LF\")\n\n// Event defines a single Server-Sent Event frame.\ntype Event struct {\n\t// Data is written as one or more data fields. Strings and byte slices are\n\t// written as-is; other values are JSON encoded.\n\tData any\n\n\t// ID sets the SSE id field.\n\tID string\n\n\t// Name sets the SSE event field.\n\tName string\n\n\t// Retry sets the SSE retry field for this event.\n\tRetry time.Duration\n}\n\nfunc writeEvent(w *bufio.Writer, event Event, jsonMarshal ...utils.JSONMarshal) error {","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/sse/event.go#L1-L33","documentation":"Server-Sent Events are line-delimited; a CR or LF byte inside an Event field (Data, ID, Name) would prematurely terminate that field and corrupt the stream framing. The SSE encoder rejects such fields with errInvalidField rather than emitting a broken stream.","triggerScenarios":"Constructing sse.Event{Name: userInput}, Event{ID: userInput}, or Event{Data: \"...\"} where the value contains '\\r' or '\\n'.","commonSituations":"Forwarding un-sanitized user input into Event.ID or Event.Name; multi-line strings in Event.Data; copying data from upstream systems that include CRLF line endings.","solutions":["Strip CR/LF from any user-controlled field before constructing the Event.","For multi-line payloads, split the data into multiple data: lines (the encoder handles []byte / multi-line data correctly when used as designed).","Validate upstream payloads at the trust boundary."],"exampleFix":"// before\nevent := sse.Event{ID: record.ID, Name: \"update\", Data: record.Note}\n\n// after\nsanitize := func(s string) string {\n    s = strings.ReplaceAll(s, \"\\r\", \"\")\n    return strings.ReplaceAll(s, \"\\n\", \"\")\n}\nevent := sse.Event{ID: sanitize(record.ID), Name: \"update\", Data: record.Note}","handlingStrategy":"validation","validationCode":"sanitize := func(s string) string {\n    s = strings.ReplaceAll(s, \"\\r\", \"\")\n    return strings.ReplaceAll(s, \"\\n\", \"\")\n}\nfor _, f := range []*string{&ev.Name, &ev.ID} { *f = sanitize(*f) }","typeGuard":"func isCRLFFree(s string) bool { return !strings.ContainsAny(s, \"\\r\\n\") }","tryCatchPattern":null,"preventionTips":["Treat any user-controlled field as tainted until stripped of CR/LF.","Encode multi-line payloads the way the SSE encoder expects (multiple data: lines).","Add a unit test asserting no field contains CR/LF after sanitization."],"tags":["sse","validation","encoding","security"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}