This rule is deprecated, and will eventually be removed.
Sending emails is security-sensitive and can expose an application to a large range of vulnerabilities.
Information Exposure
Emails often contain sensitive information which might be exposed to an attacker if he can add an arbitrary address to the recipient list.
Spamming / Phishing
Malicious user can abuse email based feature to send spam or phishing content.
Dangerous Content Injection
Emails can contain HTML and JavaScript code, thus they can be used for XSS attacks.
Email Headers Injection
Email fields such as subject
, to
, cc
, bcc
, from
are set in email "headers".
Using unvalidated user input to set those fields might allow attackers to inject new line characters in headers to craft malformed SMTP requests.
Although modern libraries are filtering new line character by default, user data used in email "headers" should always be validated.
In the past, it has led to the following vulnerabilities:
Ask Yourself Whether
- Unvalidated user input are used to set email headers.
- Email content contains data provided by users and it is not sanitized.
- Email recipient list or body are based on user inputs.
You are at risk if you answered yes to any of those questions.
Recommended Secure Coding Practices
- Use an email library which sanitizes headers (Flask-Mail or django.core.mail).
- Use html escape functions to sanitize every piece of data used to in the email body.
- Verify application logic to make sure that email base feature can not be abuse to:
- Send arbitrary email for spamming or fishing
- Disclose sensitive email content
Sensitive Code Example
smtplib
import smtplib
def send(from_email, to_email, msg):
server = smtplib.SMTP('localhost', 1025)
server.sendmail(from_email, to_email, msg) # Sensitive
Django
from django.core.mail import send_mail
def send(subject, msg, from_email, to_email):
send_mail(subject, msg, from_email, [to_email]) # Sensitive
Flask-Mail
from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
def send(subject, msg, from_email, to_email):
mail = Mail(app)
msg = Message(subject, [to_email], body, sender=from_email)
mail.send(msg) # Sensitive{code}
See