Lack of Data Validation - Emails - Elixir

Lack of Data Validation - Emails - Elixir

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