Auth0: Checking users’ email reputation in B2C scenarios with emailrep.io

Mathias Conradt
5 min readMay 22, 2020

--

Photo by Braydon Anderson on Unsplash

Checking one’s email reputation is a great way to filter for fake signups and assign user permissions according to his/her 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 just created to randomly join groups and add comments to their discussion boards.

One of many fake account and comment spam

There are different ways to solve this without shutting down the comment feature for all members entirely.
One way is to use an email reputation check when a user authenticates or signs up. Based on the reputation score, you could allow or disallow him/her to comment.

I will demonstrate how such integration of an email reputation check could look 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”.

In the background we will make use of a service called EmailRep, available at emailrep.io and also available as an open source project at https://github.com/sublime-security/emailrep.io.

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.

It’s currently in alpha stage and doesn’t require an API key for now.

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

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

Results look like below, with the important attributes for us being `reputation` and `suspicious`.

Example of a reputable user
Example of a risky user

Going back to our example: for the mentioned use case, within the Auth0 Dashboard, I register an API with permissions `read:comments` and `write:comments` and also create a role named `Reputable User` which has these two permissions assigned.

Go to the “Dashboard > APIs > Create API”:

Registering a new API

Select the “Settings” tab and enable RBAC for this API. Make sure to hit the “Save Changes” button at the bottom.

Enable RBAC for this API

Select the “Permissions” tab of the newly created API and add two permissions as below:

Setting permissions for the API

Go to the “Dashboard > Users & Roles > Roles > Create Role” and create a role as below:

Creating a new role
Assigning permissions to the role

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

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

Create a new rule in the Auth0 dashboard

The code of the rule is as below:

Code of the “Email Reputation Check” rule

The following code is also available as 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)) {
// 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 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`. If the reputation is medium or high, and the email is not suspicious, we can optionally add the user to a previously created group called “Reputable User”, which has the permission to create comments (`create:comments`) on our Meetdown platform. Only reputable users who have this role assigned can create comments, others cannot.
  • in any case, we return 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).

If a user authenticates and is reputable, he’ll be assigned the “Reputable User” role and by this have the permission ‘write:comments’, which is then also reflected in the issued access token (see `permissions` claim below):

The user is automatically assigned the role “Reputable User” but the rule.

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

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

Also the access token contains reputation info as well as permissions:

Also the access token contains reputation info as well as permissions

Our Meetdown backend API could now check for these permissions when a user tries to submit a comment. Based on the email reputation check, spammy comments by fake profiles are now avoided.

--

--

Mathias Conradt
Mathias Conradt

Written by Mathias Conradt

Cybersecurity Professional • Principal Solutions Engineer at Snyk • OWASP Member • CTF Player