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

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.

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`.

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”:

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

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

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

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”.

The code of the rule is as below:

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 frontend application showing the ID token claims, including the user’s reputation:

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.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mathias Conradt

Mathias Conradt

Cybersecurity Professional | CTO & Co-Founder at Quasr | DevSecCon Germany Chapter Lead | Snyk Ambassador | Motorbiker & MotoGP Fan | Tactical & Stealth Gamer