JAVA.SV.EMAIL.HOST

在不验证的情况下将电子邮件发送到主机。

若要建立不容易受到中间人攻击的 SSL/TLS 连接,必须确保服务器提供正确的证书。证书的特定于主机名的数据需要与服务器主机名相匹配。TLS/SSL 库提供应该使用的内置主机名验证函数。

JAVA.SV.EMAIL.HOST 检查器会标记

  • 在未将 mail.smtp.ssl.checkserveridentity 属性或 mail.smtps.ssl.checkserveridentity 属性配置为 true 的情况下创建 JavaMail javax.mail.Session 会话的情况。

  • Apache Common Email org.apache.commons.mail.SimpleEmail 类与 setSSLOnConnect(true)、setStartTLSEnabled(true) 或 setStartTLSRequired(true) 一起使用,没有调用 setSSLCheckServerIdentity(true)。

漏洞与风险

如果不验证主机名服务器的有效性,便会创建容易受到中间人攻击的连接。

缓解与预防

应始终验证主机名服务器的有效性。

漏洞代码示例 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 在第 19 行报告了 JAVA.SV.EMAIL.HOST 缺陷,指出“应该在发送电子邮件之前完成主机验证”。

修正代码示例 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;
    }
}

在此修正示例中,Klocwork 不再报告 JAVA.SV.EMAIL.HOST 缺陷,因为 mail.smtp.ssl.checkserveridentity 属性已设为 true。

漏洞代码示例 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 在第 18 行报告了 JAVA.SV.EMAIL.HOST 缺陷,指出“应该在发送电子邮件之前完成主机验证”。

修正代码示例 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();
    }
}

在此修正示例中,Klocwork 不再报告 JAVA.SV.EMAIL.HOST 缺陷,因为 setSSLCheckServerIdentity 已设为 true。

相关检查器