JAVA.SV.EMAIL.HOST
検証なしでホストに電子メールを送信しています。
中間者攻撃に脆弱ではない SSL/TLS 接続を確立するには、サーバーが正しい証明書を提示していることを確認しなければなりません。証明書のホスト名固有のデータは、サーバーのホスト名と一致している必要があります。TLS/SSL ライブラリには、組み込みのホスト名検証機能が用意されており、使用するべきです。
JAVA.SV.EMAIL.HOST チェッカーは、次の場合にフラグを立てます。
-
JavaMail javax.mail.Session セッションは、mail.smtp.ssl.checkserveridentity プロパティまたは mail.smtps.ssl.checkserveridentity プロパティが true に構成されていない状態で作成される。
-
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;
}
}
この修正された例では、mail.smtp.ssl.checkserveridentity プロパティが true に設定されているため、Klocwork は 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); // 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();
}
}
この修正された例では、setSSLCheckServerIdentity が true に設定されているため、Klocwork は JAVA.SV.EMAIL.HOST の欠陥を報告しなくなりました。
関連チェッカー
外部参考資料
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。