Description
Concatenating user input directly into an email header may let CR/LF characters introduce new headers or body content. Building password-reset links or transactional email bodies from untrusted URL or host values can also let an attacker alter the message.
Potential impact
- Attackers may insert phishing links or abuse password-reset flows.
- Users may mistake manipulated messages for trusted service email.
Remediation
- Read the email's base URL and hostname from trusted server configuration. Generate reset tokens on the server too.
- Reject CR/LF in header values and validate recipient addresses against both address syntax and permitted business use. Handle text and links in HTML bodies according to their output context.
- Distinguish SMTP recipients from displayed message headers and select the correct recipients.
Examples
These excerpts compare only construction of the To header. The actual SMTP recipients are determined by the separate to argument to smtp.SendMail. Authentication, transport protection and send-error handling are omitted. Replace the fixed address in the revised example with the actual approved recipient.
Before
go
email := r.FormValue("email")
body := "Subject: reset\r\nTo: " + email + "\r\n\r\nhello"
smtp.SendMail(addr, nil, from, to, []byte(body))
After
go
body := "Subject: reset\r\nTo: user@example.com\r\n\r\nhello"
smtp.SendMail(addr, nil, from, to, []byte(body))
Explanation:
- Before: Unvalidated
emailinput is concatenated into theToheader, so CR/LF input may alter headers or body content. - After: This example does not construct the
Toheader from user input. Dynamic recipients still need validation, and reset-URL trust must be enforced separately.