{"record":{"id":"2859b776bcf9107e","repo":"larksuite/cli","slug":"set-header-header-value-must-not-contain-cr-or-lf-2859b7","errorCode":null,"errorMessage":"set_header: header value must not contain CR or LF","messagePattern":"set_header: header value must not contain CR or LF","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":97,"sourceCode":"\tcase \"clear_reply_to\":\n\t\tremoveHeader(&snapshot.Headers, \"Reply-To\")\n\tcase \"set_body\":\n\t\treturn setBody(snapshot, op.Value, options)\n\tcase \"set_reply_body\":\n\t\treturn setReplyBody(snapshot, op.Value, options)\n\tcase \"replace_body\":\n\t\treturn replaceBody(snapshot, op.BodyKind, op.Value, options)\n\tcase \"append_body\":\n\t\treturn appendBody(snapshot, op.BodyKind, op.Value, options)\n\tcase \"set_header\":\n\t\tif err := ensureHeaderEditable(op.Name, options); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif strings.ContainsAny(op.Name, \":\\r\\n\") {\n\t\t\treturn fmt.Errorf(\"set_header: header name must not contain ':', CR, or LF\")\n\t\t}\n\t\tif strings.ContainsAny(op.Value, \"\\r\\n\") {\n\t\t\treturn fmt.Errorf(\"set_header: header value must not contain CR or LF\")\n\t\t}\n\t\tupsertHeader(&snapshot.Headers, op.Name, op.Value)\n\tcase \"remove_header\":\n\t\tif err := ensureHeaderEditable(op.Name, options); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tremoveHeader(&snapshot.Headers, op.Name)\n\tcase \"add_attachment\":\n\t\treturn addAttachment(dctx, snapshot, op.Path)\n\tcase \"remove_attachment\":\n\t\t// Priority: part_id > cid > token. When only token is set, route to\n\t\t// the large attachment path (updates header + HTML card, no MIME\n\t\t// part to remove). Otherwise, resolve to a concrete part_id.\n\t\ttgt := op.Target\n\t\tif strings.TrimSpace(tgt.PartID) == \"\" && strings.TrimSpace(tgt.CID) == \"\" {\n\t\t\tif token := strings.TrimSpace(tgt.Token); token != \"\" {\n\t\t\t\treturn removeLargeAttachment(snapshot, token)\n\t\t\t}","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L79-L115","documentation":"applyOp validates that a 'set_header' op's value contains no CR or LF. Unencoded newlines in a header value would inject extra headers, so the library rejects the op.","triggerScenarios":"Calling Apply with PatchOp{Op:\"set_header\"} where Value contains '\\r' or '\\n', e.g. a multi-line value read from user input or a config file.","commonSituations":"Setting tracking/reference headers from copied text with line breaks; values imported from JSON or CSV with embedded newlines; template output containing newlines.","solutions":["Sanitize with strings.TrimSpace or replace newlines before building the op.","For multi-line data, use RFC 2047 encoded words or folded header syntax produced by an encoding library instead of raw '\\n'.","Reject the input at your API boundary before constructing the patch."],"exampleFix":"// before\nop := PatchOp{Op: \"set_header\", Name: \"X-Note\", Value: multiLineText}\n// after\nop := PatchOp{Op: \"set_header\", Name: \"X-Note\", Value: strings.ReplaceAll(strings.ReplaceAll(multiLineText, \"\\r\", \" \"), \"\\n\", \" \")}","handlingStrategy":"validation","validationCode":"func validHeaderValue(v string) bool { return !strings.ContainsAny(v, \"\\r\\n\") }\n// before op: if !validHeaderValue(value) { sanitize or reject }","typeGuard":"func sanitizeHeaderValue(v string) string {\n    return strings.TrimSpace(strings.ReplaceAll(strings.ReplaceAll(v, \"\\r\", \" \"), \"\\n\", \" \"))\n}","tryCatchPattern":"if err := Apply(ctx, dctx, ops, opts); err != nil {\n    if strings.Contains(err.Error(), \"header value must not contain CR or LF\") {\n        return fmt.Errorf(\"collapse newlines in header value: %w\", err)\n    }\n    return err\n}","preventionTips":["Sanitize all values read from files, CSVs, or web forms before header ops.","Prefer encoded-word folding over raw newlines for long/multi-line values.","Add unit tests that feed CR/LF-containing values and expect rejection.","Centralize header-value sanitization in one helper used by all op builders."],"tags":["email","header-injection","validation"],"backgroundTag":"header-injection","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}