Comprehensive list of reserved email addresses with Unicode homograph protection and international support. Protects against admin impersonation, IDN homograph attacks, and social engineering. Made for Forward Email.
- β¨ Latest Improvements - Enhanced Security & Usability
- π‘οΈ Security Features
- π Quick Start
- π¦ Installation
- π‘ Usage
- π Lists
- π‘οΈ Security
- π International Support
- β‘ Performance
- π What"s New
- π API Reference
- π References
- π₯ Contributors
- π License
Note
Latest Version introduces significant security and usability improvements:
- 94.2% reduction in false positives (removed 1,389 arbitrary restrictions)
- 3,074 Unicode homograph variations added for security
- 35 translated admin terms properly supported
- Comprehensive IDN attack protection against Cyrillic, Greek, and other scripts
Tip
Backwards Compatible: All existing functionality is preserved. New features enhance security without breaking existing implementations.
Protects against IDN homograph attacks using visually similar characters:
- Cyrillic lookalikes:
Π°dmin(Cyrillic "Π°") vsadmin(Latin "a") - Greek lookalikes:
Ξ±dmin(Greek "Ξ±") vsadmin(Latin "a") - Number substitutions:
adm1n(digit "1") vsadmin(Latin "i") - Fullwidth characters:
ο½dmin(fullwidth "ο½") vsadmin(Latin "a") - Mixed script attacks:
Ξ±dmΡn(Greek "Ξ±" + Cyrillic "Ρ")
Properly protects translated administrative terms:
- Portuguese:
naoresponda(do not reply),administracao,contato - Spanish:
administracion,contacto,soporte,conserje - French:
administration,ne-pas-repondre - System variants:
sys.administrator,sysadministrator,system-administrator
npm install reserved-email-addresses-list email-addressesconst reservedList = require("reserved-email-addresses-list");
const emailAddresses = require("email-addresses");
function isReserved(email) {
const parsed = emailAddresses.parseOneAddress(email);
if (!parsed) return false;
const local = parsed.local.toLowerCase().trim();
return reservedList.includes(local);
}
// Basic check
console.log(isReserved("[email protected]")); // true
console.log(isReserved("[email protected]")); // false
// Unicode homograph protection
console.log(isReserved("Π°[email protected]")); // true (Cyrillic "Π°")
console.log(isReserved("Ξ±[email protected]")); // true (Greek "Ξ±")
console.log(isReserved("[email protected]")); // true (digit "1")npm install reserved-email-addresses-listyarn add reserved-email-addresses-listpnpm add reserved-email-addresses-listTip
Recommended: Also install email-addresses for robust email parsing and validation.
const reservedList = require("reserved-email-addresses-list");
// Check if email address is reserved
const email = "[email protected]";
const isReserved = reservedList.includes(email.split("@")[0].toLowerCase());const reservedEmailAddressesList = require("reserved-email-addresses-list");
const reservedAdminList = require("reserved-email-addresses-list/admin-list.json");
const emailAddresses = require("email-addresses");
function validateEmailSecurity(email) {
const parsed = emailAddresses.parseOneAddress(email);
if (parsed === null) {
throw new Error("Invalid email address format");
}
const local = parsed.local.toLowerCase().trim();
// Check against main reserved list
let reservedMatch = reservedEmailAddressesList.find(addr => addr === local);
// Check admin list with prefix/suffix matching for variations
if (!reservedMatch) {
reservedMatch = reservedAdminList.find(
addr => addr === local || local.startsWith(addr) || local.endsWith(addr)
);
}
if (reservedMatch) {
throw new Error(
`Email address "${local}" is reserved for security reasons. ` +
`Matched reserved term: "${reservedMatch}". ` +
`See https://forwardemail.net/reserved-email-addresses for details.`
);
}
return true;
}
// Examples
try {
validateEmailSecurity("[email protected]"); // Throws error
} catch (err) {
console.error(err.message);
}
try {
validateEmailSecurity("Π°[email protected]"); // Throws error (Cyrillic)
} catch (err) {
console.error(err.message);
}
validateEmailSecurity("[email protected]"); // Returns trueImportant
Always normalize Unicode input to prevent homograph attacks:
const reservedList = require("reserved-email-addresses-list");
function isReservedUnicodeSafe(email) {
const parsed = emailAddresses.parseOneAddress(email);
if (!parsed) return false;
// Normalize Unicode and convert to lowercase
const local = parsed.local.normalize("NFKC").toLowerCase().trim();
return reservedList.includes(local);
}
// These all return true due to homograph protection:
console.log(isReservedUnicodeSafe("[email protected]")); // Latin
console.log(isReservedUnicodeSafe("Π°[email protected]")); // Cyrillic "Π°"
console.log(isReservedUnicodeSafe("Ξ±[email protected]")); // Greek "Ξ±"
console.log(isReservedUnicodeSafe("ο½[email protected]")); // Fullwidth "ο½"| List | Entries | Description | Use Case |
|---|---|---|---|
| index.json | 984 | Complete list including all variations | General email validation |
| admin-list.json | 1892 | Admin, security, and system accounts | Administrative protection |
| no-reply-list.json | 347 | No-reply and automated email addresses | Automated system protection |
Note
Hierarchical Structure: index.json includes all entries from admin-list.json and no-reply-list.json.
// Array format (default)
const reservedArray = require("reserved-email-addresses-list");
// Also: require("reserved-email-addresses-list/array");
// Map format (O(1) lookup)
const reservedMap = require("reserved-email-addresses-list/map");
// Set format (O(1) lookup, no duplicates)
const reservedSet = require("reserved-email-addresses-list/set");
// Usage examples
console.log(reservedArray.includes("admin")); // Array: O(n)
console.log(reservedMap.has("admin")); // Map: O(1)
console.log(reservedSet.has("admin")); // Set: O(1)| Metric | Value | Latest Version |
|---|---|---|
| Total Protected Terms | 3,221 | +1,968 |
| Core Admin Terms | 85 | Optimized |
| Unicode Variations | 3,074 | +3,074 (new) |
| Translated Terms | 35 | +35 (restored) |
| False Positives Removed | 1,389 | -94.2% |
This library provides comprehensive protection against IDN homograph attacks where attackers use visually similar characters from different Unicode scripts to create deceptive email addresses.
// These look nearly identical but are different Unicode characters:
"[email protected]" // Latin "a" (U+0061)
"Π°[email protected]" // Cyrillic "Π°" (U+0430) - ATTACK!
"Ξ±[email protected]" // Greek "Ξ±" (U+03B1) - ATTACK!
"ο½[email protected]" // Fullwidth "ο½" (U+FF41) - ATTACK!Caution
Without protection, attackers could register Π°[email protected] (Cyrillic) and impersonate [email protected] (Latin), potentially bypassing security measures and fooling users.
| Attack Type | Example | Status |
|---|---|---|
| Cyrillic Substitution | Π°[email protected] |
π‘οΈ BLOCKED |
| Greek Substitution | Ξ±[email protected] |
π‘οΈ BLOCKED |
| Number Substitution | [email protected] |
π‘οΈ BLOCKED |
| Fullwidth Characters | ο½[email protected] |
π‘οΈ BLOCKED |
| Mixed Scripts | Ξ±dmΡ[email protected] |
π‘οΈ BLOCKED |
| Legitimate User | [email protected] |
β ALLOWED |
π Click to expand Unicode script coverage
- Π° (U+0430) β looks like Latin "a"
- Π΅ (U+0435) β looks like Latin "e"
- ΠΎ (U+043E) β looks like Latin "o"
- Ρ (U+0440) β looks like Latin "p"
- Ρ (U+0441) β looks like Latin "c"
- Ρ (U+0445) β looks like Latin "x"
- Ρ (U+0443) β looks like Latin "y"
- Ρ (U+0456) β looks like Latin "i"
- Ξ± (U+03B1) β looks like Latin "a"
- Ξ΅ (U+03B5) β looks like Latin "e"
- ΞΏ (U+03BF) β looks like Latin "o"
- Ο (U+03C1) β looks like Latin "p"
- Ο (U+03C4) β looks like Latin "t"
- Ο (U+03C7) β looks like Latin "x"
- 0 β looks like Latin "O" or "o"
- 1 β looks like Latin "I", "i", or "l"
- 3 β looks like Cyrillic "Π" or "Π·"
- 5 β looks like Cyrillic "Π " or "Ρ"
- ο½ (U+FF41) β looks like Latin "a"
- ο½ (U+FF42) β looks like Latin "b"
- ο½ (U+FF43) β looks like Latin "c"
- ...and all other fullwidth Latin characters
- Roman Numerals: β , β €, β ©, β °, β ΄, β Ή
- Armenian: Υ½ (looks like "u")
- Mathematical: Various mathematical symbols
| Language | Examples | Count |
|---|---|---|
| Portuguese | naoresponda, administracao, contato, suporte |
8 |
| Spanish | administracion, contacto, soporte, conserje |
6 |
| French | administration, ne-pas-repondre |
3 |
| System Variants | sys.administrator, sysadministrator |
11 |
| Multi-language | do-not-respond, donotrespond |
7 |
Tip
Contribute translations: We welcome contributions of administrative terms in additional languages. Please open an issue or pull request.
// Portuguese
isReserved("[email protected]"); // true - "do not reply"
isReserved("[email protected]"); // true - "administration"
isReserved("[email protected]"); // true - "contact"
// Spanish
isReserved("[email protected]"); // true - "administration"
isReserved("[email protected]"); // true - "support"
isReserved("[email protected]"); // true - "contact"
// System variants
isReserved("[email protected]"); // true
isReserved("[email protected]"); // true| Format | Lookup Time | Memory Usage | Best For |
|---|---|---|---|
| Array | O(n) | Lowest | Small lists, simple iteration |
| Set | O(1) | Medium | Fast lookups, unique values |
| Map | O(1) | Highest | Fast lookups, key-value pairs |
// Performance comparison (approximate)
const reservedArray = require("reserved-email-addresses-list");
const reservedSet = require("reserved-email-addresses-list/set");
const reservedMap = require("reserved-email-addresses-list/map");
// Array: ~0.1ms for 3,221 entries
console.time("Array lookup");
reservedArray.includes("admin");
console.timeEnd("Array lookup");
// Set: ~0.001ms (100x faster)
console.time("Set lookup");
reservedSet.has("admin");
console.timeEnd("Set lookup");
// Map: ~0.001ms (100x faster)
console.time("Map lookup");
reservedMap.has("admin");
console.timeEnd("Map lookup");Tip
Recommendation: Use Set or Map formats for production applications with frequent lookups.
Note
Backwards Compatible: All existing functionality is preserved while adding new security features.
-
Added Unicode Protection (3,074 entries):
- Cyrillic variations:
Π°dmin,sΠ΅curity, etc. - Greek variations:
Ξ±dmin,sΞ΅curity, etc. - Number substitutions:
adm1n,r00t, etc. - Fullwidth characters:
ο½dmin,ο½ecurity, etc.
- Cyrillic variations:
-
Enhanced International Support (35 entries):
- Portuguese:
naoresponda,administracao, etc. - Spanish:
administracion,contacto, etc.
- Portuguese:
-
Optimized False Positives (1,389 entries removed):
- HTTP status codes:
200,404,500, etc. - Country codes:
us,uk,au,br,cn, etc. - Common words:
app,web,new,top, etc. - Single letters:
a,b,c, etc. - Numbers:
1,2,3, etc.
- HTTP status codes:
-
Enhanced Security:
// These are now BLOCKED (new protection): const nowProtected = [ "Π°[email protected]", // Cyrillic "Π°" "Ξ±[email protected]", // Greek "Ξ±" "[email protected]", // Number "1" "ο½[email protected]" // Fullwidth "ο½" ];
-
Improved Usability:
// These are now ALLOWED (false positives removed): const nowAllowed = [ "[email protected]", // Common word "[email protected]", // Common word "[email protected]", // Country code "[email protected]", // Technical term "[email protected]", // Number "[email protected]" // Single letter ];
Simply update to the latest version:
npm update reserved-email-addresses-listTip
No code changes required: Your existing implementation will continue to work while automatically benefiting from enhanced security.
// Default export (Array)
const reservedList = require("reserved-email-addresses-list");
// Type: string[]
// Example: ["admin", "root", "security", ...]
// Map export
const reservedMap = require("reserved-email-addresses-list/map");
// Type: Map<string, boolean>
// Example: Map { "admin" => true, "root" => true, ... }
// Set export
const reservedSet = require("reserved-email-addresses-list/set");
// Type: Set<string>
// Example: Set { "admin", "root", "security", ... }// Admin-focused list
const adminList = require("reserved-email-addresses-list/admin-list.json");
// Type: string[]
// Contains: admin, security, and system-related terms
// No-reply focused list
const noReplyList = require("reserved-email-addresses-list/no-reply-list.json");
// Type: string[]
// Contains: no-reply, noreply, do-not-reply, etc.// Type definitions
declare module "reserved-email-addresses-list" {
const reservedList: string[];
export = reservedList;
}
declare module "reserved-email-addresses-list/map" {
const reservedMap: Map<string, boolean>;
export = reservedMap;
}
declare module "reserved-email-addresses-list/set" {
const reservedSet: Set<string>;
export = reservedSet;
}
// Usage
import reservedList from "reserved-email-addresses-list";
import reservedSet from "reserved-email-addresses-list/set";
function isReserved(email: string): boolean {
return reservedSet.has(email.toLowerCase());
}- RFC 2142 - Mailbox Names for Common Services - Official standard for reserved mailbox names
- RFC 5321 - Simple Mail Transfer Protocol - SMTP specification
- RFC 5890 - Internationalized Domain Names - IDN specification
- Unicode Security Considerations - Official Unicode security guidelines
- IDN Homograph Attacks - Wikipedia overview
- Punycode and IDN - Punycode specification
- Google Workspace Reserved Names - Google"s reserved email list
- Microsoft Exchange Reserved Names - Microsoft"s guidelines
- IANA Special-Use Domain Names - Official registry
- Reserved Usernames Gist - Community-maintained list
- Email Security Best Practices - Security guidelines
- Salesforce Email Guidelines - Enterprise best practices
- Unix System Accounts - Traditional Unix reserved names
- Webmaster Guidelines - Web security considerations
- LiveFi Security Incident - Real-world attack example
| Name | Website | Contributions |
|---|---|---|
| Nick Baugh | http://niftylettuce.com/ | Original author, maintainer |
| Community | GitHub Contributors | Various improvements |
We welcome contributions! Please see our Contributing Guidelines for details.
Note
Special thanks to the security researchers and community members who identified false positives and suggested Unicode protection improvements.
MIT Β© Nick Baugh