Use of an insecure channel - SMTP - Java

Use of an insecure channel - SMTP - Java

Need

Secure communication channel for SMTP

Context

  • Usage of Java 8 for developing applications with enhanced features and performance
  • Usage of javax.mail-api for sending and receiving emails
  • Usage of javax.mail library for sending and receiving emails

Description

Non compliant code

        import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

public class SendEmail {

    public static void main(String[] args) {

        final String username = "username@example.com";
        final String password = "password";

        Properties prop = new Properties();
        prop.put("mail.smtp.host", "smtp.example.com");
        prop.put("mail.smtp.port", "587");
        prop.put("mail.smtp.auth", "true");

        Session session = Session.getInstance(prop,
                new javax.mail.Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });

        try {

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("from@example.com"));
            message.setRecipients(
                    Message.RecipientType.TO,
                    InternetAddress.parse("to@example.com")
            );
            message.setSubject("Testing");
            message.setText("Hello, this is a test message");

            Transport.send(message);

            System.out.println("Done");

        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}
        
        

The above code is a simple example of sending an email using Java's javax.mail package. The SendEmail class defines a main method that sets up an SMTP server configuration, creates a message, and sends it.

The vulnerability lies in the SMTP server configuration:

                Properties prop = new Properties();
prop.put("mail.smtp.host", "smtp.example.com");
prop.put("mail.smtp.port", "587");
prop.put("mail.smtp.auth", "true");

            


Here, the properties for the SMTP server are set. The mail.smtp.auth property is set to true, requiring the client to authenticate itself to the server. However, the mail.smtp.starttls.enable property, which would start the use of the StartTLS command to upgrade a plain text connection to an encrypted (TLS or SSL) connection, is not set.

This means that the email, including any confidential information it may contain, is sent in plain text over the network. This is a serious security vulnerability, as it allows an attacker who can intercept network traffic to read the email and any sensitive information it contains.

Steps

  • Enable SSL/TLS encryption for the SMTP service
  • Update the SMTP server configuration to use the appropriate SSL/TLS settings
  • Use secure protocols such as SMTPS or STARTTLS
  • Ensure that the SMTP server certificate is valid and trusted
  • Implement proper authentication mechanisms to protect the username and password
  • Consider using a secure email library or framework that handles encryption and authentication automatically

Compliant code

        import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

public class SendEmail {

    public static void main(String[] args) {

        final String username = "username@example.com";
        final String password = "password";

        Properties prop = new Properties();
        prop.put("mail.smtp.host", "smtp.example.com");
        prop.put("mail.smtp.port", "587");
        prop.put("mail.smtp.auth", "true");
        prop.put("mail.smtp.starttls.enable", "true"); // Enable STARTTLS
        prop.put("mail.smtp.ssl.trust", "smtp.example.com"); // Trust SMTP server

        Session session = Session.getInstance(prop,
                new javax.mail.Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });

        try {

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("from@example.com"));
            message.setRecipients(
                    Message.RecipientType.TO,
                    InternetAddress.parse("to@example.com")
            );
            message.setSubject("Testing");
            message.setText("Hello, this is a test message");

            Transport.send(message);

            System.out.println("Done");

        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}
        
        

The above code is a fixed version of the previous SMTP email sending code. The vulnerability was that the SMTP service was not using SSL/TLS, which could lead to confidential information being viewed without any type of encryption.

To fix this vulnerability, the following changes were made:

1. Enabled STARTTLS: STARTTLS is a way to take an existing insecure connection and upgrade it to a secure connection using SSL/TLS. This is done by adding the property "mail.smtp.starttls.enable" and setting it to "true".

2. Trusted SMTP server: The SMTP server needs to be trusted to ensure that the SSL/TLS connection is secure. This is done by adding the property "mail.smtp.ssl.trust" and setting it to the SMTP server address.

Now, the SMTP service will use a secure SSL/TLS connection when sending emails, which will encrypt the data and prevent it from being viewed without encryption.

References