MCPcopy Create free account
hub / github.com/Mnexa-AI/e2a / TestComposeMessageSubjectCRLFNeutralized

Function TestComposeMessageSubjectCRLFNeutralized

internal/outbound/compose_test.go:90–124  ·  view source on GitHub ↗

TestComposeMessageSubjectCRLFNeutralized confirms that even if a CRLF reaches ComposeMessage (e.g. some future caller skips the API-layer validation in handleSendEmail), the Q-encoding step neutralizes it so no header smuggling can occur on the SMTP envelope. Belt + suspenders with the API-layer rej

(t *testing.T)

Source from the content-addressed store, hash-verified

88// no header smuggling can occur on the SMTP envelope. Belt + suspenders
89// with the API-layer reject in handleSendEmail.
90func TestComposeMessageSubjectCRLFNeutralized(t *testing.T) {
91 smuggled := "Hello\r\nBcc: attacker@evil.com\r\nX-Smuggled: yes"
92 raw, err := ComposeMessage(
93 "from@test.com", []string{"to@test.com"}, nil,
94 smuggled, "Body", "text/plain", "", nil, "test.dev", "", "",
95 )
96 if err != nil {
97 t.Fatalf("ComposeMessage failed: %v", err)
98 }
99 headerEnd := strings.Index(string(raw), "\r\n\r\n")
100 if headerEnd < 0 {
101 t.Fatal("no header/body separator")
102 }
103 headers := string(raw)[:headerEnd]
104 // No smuggled headers should appear on their own line.
105 for _, smuggled := range []string{"\r\nBcc: attacker@evil.com", "\r\nX-Smuggled:"} {
106 if strings.Contains(headers, smuggled) {
107 t.Errorf("composed headers contain smuggled line: %q\nfull headers:\n%s", smuggled, headers)
108 }
109 }
110 // The Subject header should round-trip back to the original literal
111 // via Go's WordDecoder, confirming the bytes survived encode/decode.
112 msg, err := mail.ReadMessage(strings.NewReader(string(raw)))
113 if err != nil {
114 t.Fatalf("parse: %v", err)
115 }
116 dec := new(mime.WordDecoder)
117 got, err := dec.DecodeHeader(msg.Header.Get("Subject"))
118 if err != nil {
119 t.Fatalf("decode subject: %v", err)
120 }
121 if got != smuggled {
122 t.Errorf("decoded subject = %q, want %q", got, smuggled)
123 }
124}
125
126func TestComposeMessageASCIISubjectUnchanged(t *testing.T) {
127 // Pure-ASCII subjects should pass through without encoded-word wrapping.

Callers

nothing calls this directly

Calls 2

ComposeMessageFunction · 0.85
GetMethod · 0.65

Tested by

no test coverage detected