To establish a SSL/TLS connection not vulnerable to man-in-the-middle attacks, it's essential to make sure the server presents the right certificate. The certificate's hostname-specific data should match the server hostname. It's not recommended to re-invent the wheel by implementing custom hostname verification. TLS/SSL libraries provide built-in hostname verification functions that should be used. This rule raises an issue when: * ``++HostnameVerifier.verify()++`` method always ``++return true++`` * a JavaMail's ``++javax.mail.Session++`` is created with a ``++Properties++`` object having no ``++mail.smtp.ssl.checkserveridentity++`` or ``++mail.smtps.ssl.checkserveridentity++`` not configured to ``++true++`` * a Apache Common Emails's ``++org.apache.commons.mail.SimpleEmail++`` is used with ``++setSSLOnConnect(true)++`` or ``++setStartTLSEnabled(true)++`` or ``++setStartTLSRequired(true)++`` without a call to ``++setSSLCheckServerIdentity(true)++`` == Noncompliant Code Example ---- URL url = new URL("https://example.org/"); HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); urlConnection.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String requestedHost, SSLSession remoteServerSession) { return true; // Noncompliant } }); InputStream in = urlConnection.getInputStream(); ---- SimpleEmail example: ---- Email email = new SimpleEmail(); email.setSmtpPort(465); email.setAuthenticator(new DefaultAuthenticator(username, password)); email.setSSLOnConnect(true); // Noncompliant; setSSLCheckServerIdentity(true) should also be called before sending the email email.send(); ---- JavaMail's example: ---- Properties props = new Properties(); 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@gmail.com", "password"); } }); ---- == Compliant Solution ---- URL url = new URL("https://example.org/"); HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); // Compliant; Use the default HostnameVerifier InputStream in = urlConnection.getInputStream(); ---- SimpleEmail example: ---- Email email = new SimpleEmail(); email.setSmtpPort(465); email.setAuthenticator(new DefaultAuthenticator(username, password)); email.setSSLOnConnect(true); email.setSSLCheckServerIdentity(true); // Compliant email.send(); ---- JavaMail's example: ---- Properties props = new Properties(); 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@gmail.com", "password"); } }); ---- == See * https://www.owasp.org/index.php/Top_10-2017_A6-Security_Misconfiguration[OWASP Top 10 2017 Category A6] - Security Misconfiguration * http://cwe.mitre.org/data/definitions/295.html[MITRE, CWE-295] - Improper Certificate Validation * Derived from FindSecBugs rule https://find-sec-bugs.github.io/bugs.htm#WEAK_HOSTNAME_VERIFIER[WEAK_HOSTNAME_VERIFIER]