Skip to main content

Lack of Data Validation - Emails

Need

Prevent usage of disposable email addresses for user registration

Context

  • Usage of Elixir (v1.10+) for building scalable and fault-tolerant applications
  • Usage of Ecto for data validation and changesets

Description

Non compliant code

defmodule MyApp.Accounts.UserChangeset do
use Ecto.Schema
import Ecto.Changeset

def changeset(user, attrs) do
user
|> cast(attrs, [:email])
|> validate_required([:email])
|> unique_constraint(:email)
end
end

The code is vulnerable because it doesn't validate whether the provided email address belongs to a disposable email service. An attacker can register and potentially reset the password for users with disposable email addresses, thereby impersonating legitimate users.

Steps

  • Create a function to validate whether an email address belongs to a disposable email service.
  • Use this function in the changeset to add an additional validation step.

Compliant code

defmodule MyApp.Accounts.UserChangeset do
use Ecto.Schema
import Ecto.Changeset

def changeset(user, attrs) do
user
|> cast(attrs, [:email])
|> validate_required([:email])
|> validate_email()
|> unique_constraint(:email)
end

defp validate_email(changeset) do
if changeset.valid? && disposable_email?(changeset.changes.email) do
add_error(changeset, :email, "Disposable email addresses not allowed")
else
changeset
end
end

defp disposable_email?(email) do
# Implement your disposable email check here
end
end

This code is secure because it adds an additional validation step to check whether the provided email address belongs to a disposable email service. If it does, an error is added to the changeset, and the registration request is rejected.

References