Another night shift, another wave of spam signups trying to use those disposable email domains. Saw the same pattern in the logs for the third time this week and finally decided to automate the block at the source.
Auth0 rules to the rescue. It's a simple function that checks the user's email domain against a maintained list. I'm using a static list in the rule for simplicity, but you could fetch it from an external API if you're feeling fancy. Here's the meat of it:
```javascript
function (user, context, callback) {
// List of disposable email domains (truncated for example)
const disposableDomains = [
'mailinator.com',
'guerrillamail.com',
'10minutemail.com',
'tempmail.com',
'yopmail.com'
];
const userEmailDomain = user.email.split('@')[1].toLowerCase();
if (disposableDomains.includes(userEmailDomain)) {
return callback(new UnauthorizedError('Disposable email domains are not allowed.'));
}
// User is allowed to proceed
callback(null, user, context);
}
```
**Pitfalls & Notes:**
* You need to keep that domain list updated. I have a small cron job that pulls a fresh list from a public repo and updates a Auth0 rule variable, but that's a story for another post.
* This runs on every login/signup, so keep the list reasonably sized for performance.
* Watch out for false positives if you have any legitimate users on a domain that gets added to these lists (rare, but possible).
Works like a charm. Signup spam dropped to zero after deploying this. Saved the on-call from a few noisy alerts about weird login attempts.
Pager duty survivor.
NightOps
Your approach with a static list is a decent first line of defense, but it's inherently brittle. Those domain lists change daily, and a static array in a rule will be outdated within a week. Using a rule variable updated by a cron job is definitely the better path, though I'd argue for pushing that list to a small, highly-available key-value store like Redis instead.
Fetching from an external API on every authentication attempt introduces latency and a new point of failure. A more resilient pattern is to have your cron job update the cached list, and your Auth0 rule reads from that cache. This also avoids hitting Auth0's rule variable size limits if you're using a comprehensive list with thousands of domains.
Also, consider the false positive risk with subdomains. Your `userEmailDomain` extraction won't catch something like `[email protected]`. You need to check if the extracted domain *ends with* any string in your blocklist, not just direct equality.