Skip to main content

Email uniqueness not properly verified

Need

Ensure email uniqueness verification during registration process

Context

  • Usage of Dart for building cross-platform mobile, web, and desktop applications
  • Usage of Shelf for managing and organizing data in a Node.js application

Description

Non compliant code

import 'package:shelf/shelf.dart' as shelf;

class User {
String email;
User(this.email);
}

List<User> users = [];

shelf.Response handleRegister(shelf.Request request) {
var email = request.url.queryParameters['email'];
if (users.any((user) => user.email == email)) {
return shelf.Response.ok('Email already registered');
} else {
users.add(User(email));
return shelf.Response.ok('Registration successful');
}
}

In the above Dart code, we have a simple user registration system using the Shelf framework. The handleRegister function is responsible for handling the user registration process.

The function first retrieves the email from the request's query parameters. It then checks if the email is already registered by iterating over the users list and comparing each user's email with the provided email.

If the email is found in the list, the function returns a response indicating that the email is already registered. Otherwise, it creates a new User object with the provided email and adds it to the users list. Finally, it returns a response indicating that the registration was successful.

The vulnerability here is that the system allows the plus character in the email registration process. This means that an attacker could use the same email with different plus suffixes to create multiple accounts. For example, an attacker could register [email protected], [email protected], and [email protected], and all these emails would be treated as separate accounts by the system, even though they all point to the same email address.

Steps

  • Normalize the email address before storing and comparing it. This can be done by removing all characters after and including the '+' sign in the local part of the email address.
  • Implement a function to validate the email format. This function should check if the email contains a '+' character. If it does, the function should remove everything from the '+' character to the end of the local part of the email address.
  • Use this function to normalize the email address in the 'handleRegister' function before checking if the email is already registered and before storing the new user's email.
  • Ensure that this normalization process is applied consistently throughout the application, wherever email addresses are processed or compared.

Compliant code

import 'package:shelf/shelf.dart' as shelf;

class User {
String email;
User(this.email);
}

List<User> users = [];

String normalizeEmail(String email) {
var parts = email.split('@');
var localPart = parts[0];
var domainPart = parts[1];
if (localPart.contains('+')) {
localPart = localPart.split('+')[0];
}
return '$localPart@$domainPart';
}

shelf.Response handleRegister(shelf.Request request) {
var email = request.url.queryParameters['email'];
var normalizedEmail = normalizeEmail(email);
if (users.any((user) => user.email == normalizedEmail)) {
return shelf.Response.ok('Email already registered');
} else {
users.add(User(normalizedEmail));
return shelf.Response.ok('Registration successful');
}
}

The updated code includes a new function normalizeEmail that normalizes the email address by removing all characters after and including the '+' sign in the local part of the email address. This function is used in the handleRegister function to normalize the email address before checking if the email is already registered and before storing the new user's email.

The normalizeEmail function works by splitting the email address into the local part and the domain part. If the local part contains a '+' character, the function removes everything from the '+' character to the end of the local part. The function then returns the normalized email address.

In the handleRegister function, the email address from the request is first normalized using the normalizeEmail function. The normalized email address is then used to check if the email is already registered and to store the new user's email.

This normalization process ensures that email addresses are consistently processed and compared throughout the application, preventing an attacker from abusing the '+' character to create several accounts with the same email address.

References