diff --git a/src/main/java/org/simplejavamail/mailer/Mailer.java b/src/main/java/org/simplejavamail/mailer/Mailer.java
index 88d834125..114e4f5e4 100644
--- a/src/main/java/org/simplejavamail/mailer/Mailer.java
+++ b/src/main/java/org/simplejavamail/mailer/Mailer.java
@@ -4,6 +4,7 @@
import org.hazlewood.connor.bottema.emailaddress.EmailAddressValidator;
import org.simplejavamail.MailException;
import org.simplejavamail.converter.internal.mimemessage.MimeMessageHelper;
+import org.simplejavamail.email.AttachmentResource;
import org.simplejavamail.email.Email;
import org.simplejavamail.email.Recipient;
import org.simplejavamail.mailer.config.ProxyConfig;
@@ -20,6 +21,7 @@
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import java.util.EnumSet;
+import java.util.Map;
import java.util.Properties;
import static java.lang.String.format;
@@ -341,9 +343,18 @@ public final synchronized void sendMail(final Email email, @SuppressWarnings("Sa
mailSender.send(email, async);
}
}
-
+
/**
* Validates an {@link Email} instance. Validation fails if the subject is missing, content is missing, or no recipients are defined.
+ *
+ * It also checks for illegal characters that would facilitate injection attacks:
+ *
+ *
+ * - http://www.cakesolutions.net/teamblogs/2008/05/08/email-header-injection-security
+ * - https://security.stackexchange.com/a/54100/110048
+ * - https://www.owasp.org/index.php/Testing_for_IMAP/SMTP_Injection_(OTG-INPVAL-011)
+ * - http://cwe.mitre.org/data/definitions/93.html
+ *
*
* @param email The email that needs to be configured correctly.
* @return Always true
(throws a {@link MailException} exception if validation fails).
@@ -353,6 +364,28 @@ public final synchronized void sendMail(final Email email, @SuppressWarnings("Sa
@SuppressWarnings({ "SameReturnValue", "WeakerAccess" })
public boolean validate(final Email email)
throws MailException {
+ // check for illegal values
+ scanForInjectionAttack(email.getSubject(), "email.subject");
+ for (Map.Entry headerEntry : email.getHeaders().entrySet()) {
+ scanForInjectionAttack(headerEntry.getKey(), "email.header.mapEntryKey");
+ scanForInjectionAttack(headerEntry.getValue(), "email.header." + headerEntry.getKey());
+ }
+ for (AttachmentResource attachment : email.getAttachments()) {
+ scanForInjectionAttack(attachment.getName(), "email.attachment.name");
+ }
+ for (AttachmentResource embeddedImage : email.getEmbeddedImages()) {
+ scanForInjectionAttack(embeddedImage.getName(), "email.embeddedImage.name");
+ }
+ scanForInjectionAttack(email.getFromRecipient().getName(), "email.fromRecipient.name");
+ scanForInjectionAttack(email.getFromRecipient().getAddress(), "email.fromRecipient.address");
+ scanForInjectionAttack(email.getReplyToRecipient().getName(), "email.replyToRecipient.name");
+ scanForInjectionAttack(email.getReplyToRecipient().getAddress(), "email.replyToRecipient.address");
+ for (Recipient recipient : email.getRecipients()) {
+ scanForInjectionAttack(recipient.getName(), "email.recipient.name");
+ scanForInjectionAttack(recipient.getAddress(), "email.recipient.address");
+ }
+
+ // check for mandatory values
if (email.getText() == null && email.getTextHTML() == null) {
throw new MailerException(MailerException.MISSING_CONTENT);
} else if (email.getSubject() == null || email.getSubject().equals("")) {
@@ -377,6 +410,16 @@ public boolean validate(final Email email)
}
return true;
}
+
+ /**
+ * @param value Value checked for suspicious newline characters "\n", "\r" and "%0A" (as acknowledged by SMTP servers).
+ * @param valueLabel The name of the field being checked, used for reporting exceptions.
+ */
+ private static void scanForInjectionAttack(String value, String valueLabel) {
+ if (value != null && (value.contains("\n") || value.contains("\r") || value.contains("%0A"))) {
+ throw new MailerException(format(MailerException.INJECTION_SUSPECTED, valueLabel, value));
+ }
+ }
/**
* Refer to {@link MimeMessageHelper#signMessageWithDKIM(MimeMessage, Email)}
diff --git a/src/main/java/org/simplejavamail/mailer/MailerException.java b/src/main/java/org/simplejavamail/mailer/MailerException.java
index 3a213981e..cc2f0b3d3 100644
--- a/src/main/java/org/simplejavamail/mailer/MailerException.java
+++ b/src/main/java/org/simplejavamail/mailer/MailerException.java
@@ -17,6 +17,7 @@ class MailerException extends MailException {
static final String MISSING_RECIPIENT = "Email is not valid: missing recipients";
static final String MISSING_SUBJECT = "Email is not valid: missing subject";
static final String MISSING_CONTENT = "Email is not valid: missing content body";
+ static final String INJECTION_SUSPECTED = "Suspected of injection attack, field: %s with suspicious value: %s";
MailerException(final String message) {
super(message);