Skip to main content

Use of an insecure channel - SMTP

Need

Secure transmission of confidential information over SMTP

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and APIs
  • Usage of Nodemailer for sending emails

Description

Non compliant code

import express from 'express';
import nodemailer from 'nodemailer';

const app = express();

app.post('/send-email', (req, res) => {
const { to, subject, text } = req.body;

const transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 587,
auth: {
user: '[email protected]',
pass: 'your-password',
},
});

const mailOptions = {
from: '[email protected]',
to,
subject,
text,
};

transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error('Error sending email:', error);
res.status(500).json({ error: 'Failed to send email' });
} else {
console.log('Email sent:', info.response);
res.status(200).json({ message: 'Email sent successfully' });
}
});
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The vulnerability in this code is the use of an insecure channel for sending emails via SMTP. The code uses the nodemailer library to send emails, but the configuration of the SMTP service does not use SSL encryption.

In the code, the createTransport function is used to create a transporter object for sending emails. The host and port options are set to the SMTP server details, but there is no option specified for enabling SSL encryption.

Without SSL encryption, any confidential information sent through this insecure channel can be viewed by attackers without any encryption. This includes the email content, subject, and recipient information.

To fix this vulnerability, the application should be deployed over an encrypted communication channel using SSL secure protocols. This can be achieved by configuring the SMTP service to use SSL/TLS encryption for secure email transmission.

Steps

  • Update the SMTP configuration to use SSL/TLS encryption
  • Change the SMTP host to a secure SMTP server
  • Update the SMTP port to the appropriate secure port
  • Remove the 'auth' property from the transporter configuration
  • Remove the 'user' and 'pass' properties from the 'auth' object
  • Implement a secure method for storing and retrieving the email credentials
  • Update the email sending logic to use the secure SMTP configuration

Compliant code

import express from 'express';
import nodemailer from 'nodemailer';

const app = express();

app.post('/send-email', (req, res) => {
const { to, subject, text } = req.body;

const transporter = nodemailer.createTransport({
host: 'smtp.example.com',
port: 465,
secure: true,
});

const mailOptions = {
from: '[email protected]',
to,
subject,
text,
};

transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.error('Error sending email:', error);
res.status(500).json({ error: 'Failed to send email' });
} else {
console.log('Email sent:', info.response);
res.status(200).json({ message: 'Email sent successfully' });
}
});
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The fixed code addresses the vulnerability by ensuring that the communication channel used for sending emails is secure. Here's an explanation of the changes made:

  1. Importing necessary modules: The code imports the required modules, express and nodemailer, which are used to create the server and send emails, respectively.

  2. Creating an Express server: The code creates an instance of the Express server using express().

  3. Handling the POST request: The code defines a route for handling the POST request to send an email. It expects the request body to contain the recipient's email address (to), subject, and text of the email.

  4. Creating a secure transporter: The code creates a transporter object using nodemailer.createTransport(). The transporter is configured to use a secure connection by setting the secure option to true. This ensures that the SMTP service uses SSL for encryption.

  5. Configuring email options: The code defines the email options, including the sender's email address (from), recipient's email address (to), subject, and text of the email. These options are passed to the sendMail() method of the transporter.

  6. Sending the email: The code calls the sendMail() method of the transporter, passing the email options. It handles the response and error using a callback function. If an error occurs, it logs the error and sends a 500 response with an error message. If the email is sent successfully, it logs the response and sends a 200 response with a success message.

  7. Starting the server: The code starts the Express server and listens on port 3000. It logs a message indicating that the server is running.

By configuring the transporter to use a secure connection (SSL), the fixed code ensures that the communication channel used for sending emails is encrypted, addressing the vulnerability.

References