identity & security

Checking Users Email Reputation Score During Authentication

Checking a user's email reputation is a great way to filter for fake signups and assign user permissions according to their reputation, especially in B2C scenarios.

I love Meetup.com. It's a great way to organize or attend events with and for like-minded people around any topic in your region. I'm using the platform both as an organizer as well as an attendee.

Recently though, the platform has seen a lot of spam, which becomes quite annoying. Fake accounts that are just created to randomly join groups and add comments to their discussion boards.

Meetup Fake Account Sample

There are different ways to solve this without shutting down the comment feature for all members entirely.

One way, and the way we'll be focusing on here, is to use an email reputation check when a user authenticates or signs up. Based on the reputation score, you could allow or disallow that user to comment.

I will demonstrate what the integration of an email reputation check looks like when using Auth0 as IDaaS (identity as a service platform) for user registration and authentication. I will call my fictitious application and backend/API "Meetdown".

Using EmailRep.io

In the background, we will make use of a service called EmailRep, available at emailrep.io and also available as an open-source project.

EmailRep is a system of crawlers, scanners, and enrichment services that collects data on email addresses, domains, and internet personas.

EmailRep uses hundreds of data points from social media profiles, professional networking sites, dark web credential leaks, data breaches, phishing kits, phishing emails, spam lists, open mail relays, domain age and reputation, deliverability, and more to predict the risk of an email address.

EmailRep is currently in alpha stage and doesn't require an API key yet.

The API can be called by a simple request with the user's email address as a parameter:

GET https://emailrep.io/<email_address>

The image below shows what the results for that request look like, with the important attributes for us being

reputation
and
suspicious
.

High Email Reputation Score Example

Risky Email Reputation Score Example

Using the Auth0 Dashboard

In order to check for a malicious e-mail using EmailRep.io, first create a free Auth0 account.

Creating the Email Reputation Score Rule

In order to run an email reputation check when a user authenticates in Auth0, we create a Rule in the Auth0 dashboard.

Go to the "Dashboard > Rules > Create Rule" and create a rule named "Email Reputation Check".

Auth0 Dashboard: Create a Rule

Auth0 Dashboard: Rule Code

Paste the following code block into the code sandbox for the "Email Reputation Check" rule. The code is also available as a Gist on Github:

function (user, context, callback) {
  // skip if emailrep.io metadata is already there
  if (user.app_metadata && user.app_metadata.emailrep) {
    context.idToken['https://emailrep.io/reputation'] = user.app_metadata.emailrep.reputation;
    context.idToken['https://emailrep.io/suspicious'] = user.app_metadata.emailrep.suspicious;
    context.accessToken['https://emailrep.io/reputation'] = user.app_metadata.emailrep.reputation;
    context.accessToken['https://emailrep.io/suspicious'] = user.app_metadata.emailrep.suspicious;    
    return callback(null, user, context);
  }
  request.get('https://emailrep.io/' + user.email, {
    json: true
  }, (error, response, body) => {
    if (error || (response && response.statusCode !== 200)) {
      console.log(error);
      // swallow emailrep.io api errors and just continue login
      return callback(null, user, context);
    }
    // if we reach here, it means EmailRep returned info and we'll add it to the metadata
    user.app_metadata = user.app_metadata || {};
    user.app_metadata.emailrep = body;
    auth0.users.updateAppMetadata(user.user_id, user.app_metadata);
    context.idToken['https://emailrep.io/reputation'] = user.app_metadata.emailrep.reputation;
    context.idToken['https://emailrep.io/suspicious'] = user.app_metadata.emailrep.suspicious;
    context.accessToken['https://emailrep.io/reputation'] = user.app_metadata.emailrep.reputation;
    context.accessToken['https://emailrep.io/suspicious'] = user.app_metadata.emailrep.suspicious;
    return callback(null, user, context);
  });
}

This rule does the following:

  • Check if the email reputation score for this user has already been checked before. If so, there should be data in his user profile under
    user.app_metadata.emailrep
    .
  • If an email reputation check hasn't been done for this user yet, we'll call the emailrep.io API and store the result in the user profile under
    user.app_metadata.emailrep
    .
  • Auth0 returns the

    reputation
    and
    suspicious
    value in the ID and access token for further evaluation on the client application (via ID token) and/or backend (via access token).

    The frontend application showing the ID token claims, including the user's reputation:

User Profile in Client Application

The access token now contains reputation information as well:

Decoding a JWT on jwt.io

Both our Meetdown frontend as well as backend API could now check for these reputation claims in the ID token (in the frontend) and access token (in the backend) respectively when a user tries to submit a comment. Based on the email reputation check, spammy comments by fake profiles are now blocked.

Thank you for following along and let me know if you have any questions in the comments below.