JAVA.SV.EMAIL.HOST
Sending e-mails to Host without validation.
To establish an SSL/TLS connection that is not vulnerable to man-in-the-middle attacks, you must ensure that the server presents the correct certificate. The certificate’s hostname-specific data needs to match the server hostname. TLS/SSL libraries provide built-in hostname verification functions that should be used.
The JAVA.SV.EMAIL.HOST checker flags cases where
-
a JavaMail javax.mail.Session session is created without a mail.smtp.ssl.checkserveridentity property or a mail.smtps.ssl.checkserveridentity property configured to true.
-
an Apache Common Email org.apache.commons.mail.SimpleEmail class is used with setSSLOnConnect(true), setStartTLSEnabled(true), or setStartTLSRequired(true) and there is no call to setSSLCheckServerIdentity(true).
Vulnerability and risk
If you do not verify the validity of the hostname server, you create connections that are vulnerable to man-in-the-middle attacks.
Mitigation and prevention
Always verify the validity of the hostname server.
Vulnerable code example 1
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import java.io.IOException;
import java.util.Properties;
public class JavaEmailHostSecured {
public Session getEmailSession(String args[]) throws IOException {
Properties props = new Properties();
String username = "username@gmail.com", password = "password";
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // Noncompliant; Session is created without having "mail.smtp.ssl.checkserveridentity" set to true
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
return session;
}
}
Klocwork reports a JAVA.SV.EMAIL.HOST defect on line 19, indicating, "Host validation should be done before sending e-mails."
Fixed code example 1
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import java.io.IOException;
import java.util.Properties;
public class JavaEmailHostSecured {
public Session getEmailSession(String args[]) throws IOException {
Properties props = new Properties();
String username = "username@gmail.com", password = "password";
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.ssl.checkserveridentity", true); // Compliant
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
return session;
}
}
In this fixed example, Klocwork no longer reports a JAVA.SV.EMAIL.HOST defect because the mail.smtp.ssl.checkserveridentity property is set to true.
Vulnerable code example 2
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import java.io.IOException;
public class SimpleEmailHost {
public void sendEmail() throws IOException, EmailException {
String username = "username@gmail.com", password = "password";
Email email = new SimpleEmail();
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true); // Noncompliant;
email.setStartTLSEnabled(true);// Noncompliant;
email.setStartTLSRequired(true);// Noncompliant; setSSLCheckServerIdentity(true) should also be called before sending the email
email.send();
}
}
Klocwork reports a JAVA.SV.EMAIL.HOST defect on line 18, indicating, "Host validation should be done before sending e-mails."
Fixed code example 2
import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import java.io.IOException;
public class SimpleEmailHost {
public void sendEmail() throws IOException, EmailException {
String username = "username@gmail.com", password = "password";
Email email = new SimpleEmail();
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true);
email.setStartTLSEnabled(true);
email.setStartTLSRequired(true);
email.setSSLCheckServerIdentity(true); // Compliant
email.send();
}
}
In this fixed example, Klocwork no longer reports a JAVA.SV.EMAIL.HOST defect because setSSLCheckServerIdentity is set to true.
Related checkers
External guidance
- CWE-295: Improper Certificate Validation
- OWASP A6:2017 Security Misconfiguration
- OWASP A2:2021 Cryptographic Failures
- OWASP A5:2021 Security Misconfiguration
- OWASP A7:2021 Identification and Authentication Failures
- V-222555 (APSC-DV-001860): The application must use mechanisms meeting the requirements of applicable federal laws, Executive Orders, directives, policies, regulations, standards, and guidance for authentication to a cryptographic module.
Security training
Application security training materials provided by Secure Code Warrior.