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.