Email Header Injection
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and psalm — both specialist/SAST tools — as the means of catching unsanitised user input flowing into mail() headers. A default linter won't flag this; it requires a dedicated static analysis rule targeting the specific mail() call pattern with tainted input.
Closest to 'simple parameterised fix' (e3). The quick_fix is to swap PHP's mail() for a library like Symfony Mailer or PHPMailer. This is more than a one-line patch (it requires replacing mail() calls and adjusting how headers/recipients are passed), but it's a contained substitution within one component rather than a cross-cutting refactor.
Closest to 'localised tax' (b3). The vulnerability applies to web and CLI contexts wherever mail() is used, but it is scoped to the mail-sending component(s) of the codebase. Once the fix is in place (library swap), the rest of the codebase is largely unaffected. It does not impose an ongoing structural tax on unrelated work streams.
Closest to 'serious trap' (t7). The misconception field reveals the trap: developers believe email injection only enables spam, but it also enables domain spoofing, BCC abuse, and bypassing SPF/DKIM since mail originates from the legitimate server. Additionally, Subject being injectable contradicts the intuition that only To/From/CC fields are dangerous — this contradicts how similar injection concepts are understood elsewhere, warranting t7.
Also Known As
TL;DR
Explanation
PHP's mail() function constructs raw SMTP headers. If user-supplied data (a name or subject) contains \r\n, an attacker can inject additional headers — Bcc:, Cc:, or a new message body — turning the server into a spam relay. Always strip newlines from any value passed to mail() headers. Better still, use a dedicated library such as Symfony Mailer or PHPMailer which sanitise headers automatically, and validate email addresses with filter_var($addr, FILTER_VALIDATE_EMAIL).
Common Misconception
Why It Matters
Common Mistakes
- Passing user-supplied email addresses directly to the headers parameter of PHP's mail() function.
- Not stripping newline characters from email addresses or subject lines before using them in headers.
- Building header strings manually via concatenation instead of using a library like PHPMailer or Symfony Mailer.
- Forgetting that Subject is also injectable — newlines in the subject can inject additional headers.
Code Examples
mail($to, $_POST['subject'], $body); // subject may contain \r\nBcc: attacker@evil.com
$subject = str_replace(["\r", "\n"], '', $_POST['subject']);
mail($to, $subject, $body);