logo

Lack of Data Validation - Emails - Elixir


Need

Prevent usage of disposable email addresses for user registration


Context

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

Description

Insecure Code Example

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

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

Secure Code Example

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

  • 199 - Lack of Data Validation - Emails

  • Last updated

    2023/09/18