Skip to main content

Email flooding

Need

Mitigation of email flooding attacks

Context

  • Usage of Scala for building scalable and functional applications
  • Usage of play.api.libs.mailer for sending emails in a Play Framework application

Description

Non compliant code

import play.api.libs.mailer._

class EmailController @Inject()(mailerClient: MailerClient) extends Controller {
def sendEmail = Action { request =>
val email = Email(
"Hello",
"[email protected]",
Seq("[email protected]"),
bodyText = Some("A text message"),
bodyHtml = Some("<html><body><p>An <b>html</b> message</p></body></html>")
)
mailerClient.send(email)
Ok("Sent")
}
}

The above code is a simple email controller in a Scala backend application that uses the Play framework. It uses the Play Mailer library to send an email when the sendEmail action is triggered.

The vulnerability here is that there is no control over how many times the sendEmail action can be triggered. An attacker can repeatedly call this action to send a large number of emails to the recipient, causing an email flood. This can lead to the saturation of the victim's inbox and potentially cause denial of service as the victim may not be able to receive any more emails.

Furthermore, the email sender ("[email protected]") and recipient ("[email protected]") are hardcoded into the application, meaning the attacker can only flood the inbox of the hardcoded recipient. However, if the attacker gains access to the source code, they can modify these addresses to target different victims.

Also, the email content is static and does not require any user input, making it easier for the attacker to automate the email flooding process.

Steps

  • Implement rate limiting to restrict the number of emails that can be sent within a certain time period.
  • Add CAPTCHA verification to prevent automated scripts from flooding the email server.
  • Implement email validation to ensure that the recipient email addresses are valid and not being abused.
  • Consider implementing a queue system to handle email sending asynchronously and prevent flooding the email server.
  • Monitor email sending patterns and set up alerts for suspicious activity or unusual spikes in email volume.
  • Regularly review and update email sending policies to ensure they align with best practices and security standards.

Compliant code

import play.api.libs.mailer._
import play.api.mvc._
import javax.inject.Inject
import scala.concurrent.ExecutionContext
import play.api.libs.mailer.MailerClient
import play.filters.csrf.CSRF

class EmailController @Inject()(mailerClient: MailerClient, cc: ControllerComponents)(implicit ec: ExecutionContext) extends AbstractController(cc) {
private val MAX_EMAILS_PER_HOUR = 100
private var emailsSent = 0
private var lastEmailSentAt = System.currentTimeMillis()

def sendEmail = Action { request =>
if (emailsSent >= MAX_EMAILS_PER_HOUR && System.currentTimeMillis() - lastEmailSentAt < 3600000) {
BadRequest("Too many requests")
} else {
val email = Email(
"Hello",
"[email protected]",
Seq("[email protected]"),
bodyText = Some("A text message"),
bodyHtml = Some("<html><body><p>An <b>html</b> message</p></body></html>")
)
mailerClient.send(email)
emailsSent += 1
lastEmailSentAt = System.currentTimeMillis()
Ok("Sent")
}
}
}

The updated code includes a rate limiting mechanism to prevent email flooding. The MAX_EMAILS_PER_HOUR constant is used to define the maximum number of emails that can be sent within an hour. The emailsSent variable keeps track of the number of emails sent within the current hour, and lastEmailSentAt stores the time when the last email was sent.

Before sending an email, the code checks if the maximum number of emails has already been sent within the last hour. If the limit has been reached, the server responds with a "Too many requests" message. Otherwise, the email is sent, the emailsSent counter is incremented, and lastEmailSentAt is updated with the current time.

This solution helps to prevent email flooding by limiting the number of emails that can be sent within a certain time period. However, it is recommended to also implement additional measures such as CAPTCHA verification, email validation, a queue system for handling email sending, monitoring of email sending patterns, and regular review and update of email sending policies.

References