Email Injection with Jwt Tokens
How Email Injection Manifests in Jwt Tokens
Email injection in JWT tokens occurs when attackers manipulate email-related claims to exploit downstream systems. The most common vulnerability appears in the email claim within the payload, where malicious actors inject newline characters or SMTP commands to alter email headers when the token is processed by email systems.
A typical attack vector involves crafting a JWT with an email claim like:
{
"email": "[email protected]\nSubject: You've won!\nBcc: [email protected], [email protected]\nContent-Type: text/html\n\n<img src='http://malicious.com/track'>"
}When this token is decoded and the email claim is used to send notifications, the injected headers can cause the system to send emails to unintended recipients, modify email subjects, or include malicious content.
Another Jwt Tokens-specific manifestation occurs in multi-tenant applications where JWTs contain tenant-specific email domains. Attackers can exploit the aud (audience) claim combined with email injection to bypass tenant isolation. For example:
{
"aud": "tenant-1234",
"email": "[email protected]\nCc: [email protected]\nSubject: Password reset required"
}The vulnerability becomes critical when Jwt Tokens are used for authentication in email-based workflows. Consider a password reset system that validates a JWT and sends reset instructions. If the email claim isn't properly sanitized, an attacker could inject additional recipients or modify the email content.
Email injection also appears in JWT-based API keys for email services. When the JWT contains SMTP credentials or email configuration, attackers can manipulate the payload to include command injection payloads that execute when the token is used to establish email connections.
The risk compounds when Jwt Tokens are used in microservices architectures where email processing happens in separate services. A compromised JWT can propagate through the system, with each service potentially vulnerable to different aspects of the injection.
Jwt Tokens-Specific Detection
Detecting email injection in JWT tokens requires examining both the token structure and how claims are processed. Start by validating the email claim format using strict regular expressions that reject newline characters and suspicious patterns:
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
function validateEmailClaim(payload) {
if (!payload.email) return true;
if (!emailRegex.test(payload.email)) {
throw new Error('Invalid email format in JWT');
}
if (payload.email.includes('\n') || payload.email.includes('\r')) {
throw new Error('Email claim contains newline characters');
}
return true;
}For comprehensive detection, implement claim validation middleware that inspects all JWT claims before processing:
const jwt = require('jsonwebtoken');
const validator = require('validator');
function jwtEmailInjectionDetector(token) {
try {
const decoded = jwt.decode(token, { complete: true });
if (!decoded || !decoded.payload) return false;
const payload = decoded.payload;
if (payload.email && typeof payload.email === 'string') {
if (payload.email.includes('\n') || payload.email.includes('\r')) {
return {
risk: 'high',
finding: 'Newline characters detected in email claim',
severity: 'critical'
};
}
if (!validator.isEmail(payload.email)) {
return {
risk: 'high',
finding: 'Invalid email format in JWT',
severity: 'high'
};
}
const suspiciousHeaders = ['subject:', 'bcc:', 'cc:', 'content-type:', 'to:'];
const lowerEmail = payload.email.toLowerCase();
for (const header of suspiciousHeaders) {
if (lowerEmail.includes(header)) {
return {
risk: 'critical',
finding: `Email claim contains suspicious header: ${header}`,
severity: 'critical'
};
}
}
}
return { risk: 'none', finding: 'No email injection detected' };
} catch (error) {
return { risk: 'unknown', finding: 'Token parsing failed', severity: 'medium' };
}
}middleBrick's scanner automatically detects email injection vulnerabilities by testing JWT endpoints with crafted payloads containing newline characters and SMTP commands. The scanner attempts to decode tokens and analyze claims for injection patterns, providing severity ratings and remediation guidance.
Runtime detection should also monitor for anomalous email patterns. Implement logging that tracks email claim usage and flags unusual patterns like multiple recipients in a single claim or unexpected domain changes.
Jwt Tokens-Specific Remediation
Remediation for email injection in JWT tokens requires defense-in-depth across token generation, validation, and processing. Start with strict claim validation at the token creation stage:
const jwt = require('jsonwebtoken');
const validator = require('validator');
function createSecureJwt(payload, secret, options = {}) {
const securePayload = { ...payload };
if (securePayload.email) {
if (!validator.isEmail(securePayload.email)) {
throw new Error('Invalid email format');
}
if (securePayload.email.includes('\n') || securePayload.email.includes('\r')) {
throw new Error('Email claim contains newline characters');
}
if (securePayload.email.length > 254) {
throw new Error('Email claim too long');
}
}
return jwt.sign(securePayload, secret, {
issuer: options.issuer || 'your-app',
audience: options.audience,
expiresIn: options.expiresIn || '1h',
...options
});
}Implement claim sanitization when processing tokens to ensure downstream systems receive only safe data:
function sanitizeEmailClaim(email) {
if (typeof email !== 'string') return null;
const sanitized = email
.replace(/\r/g, '')
.replace(/\n/g, '')
.trim();
return sanitized;
}
function processJwtWithSanitization(token, secret) {
try {
const decoded = jwt.verify(token, secret);
if (decoded.email) {
decoded.email = sanitizeEmailClaim(decoded.email);
if (!validator.isEmail(decoded.email)) {
throw new Error('Sanitized email is invalid');
}
}
return decoded;
} catch (error) {
throw new Error(`JWT processing failed: ${error.message}`);
}
}For applications using JWTs in email workflows, implement context-aware validation that considers the intended use:
function validateEmailForContext(email, context) {
if (context === 'password-reset') {
const domain = email.split('@')[1];
if (!allowedDomains.has(domain)) {
throw new Error('Email domain not allowed for password reset');
}
}
if (context === 'notification') {
if (email.includes('@example.com')) {
throw new Error('Notification emails cannot use example domains');
}
}
return true;
}
function secureJwtProcessing(token, secret, context) {
const decoded = jwt.verify(token, secret);
if (decoded.email) {
validateEmailForContext(decoded.email, context);
decoded.email = sanitizeEmailClaim(decoded.email);
}
return decoded;
}Consider using JWT libraries with built-in claim validation and consider implementing a claim whitelist approach where only explicitly allowed claims are processed. This prevents unexpected claims from being interpreted as email headers or commands.
For enterprise deployments, middleBrick's Pro plan offers continuous monitoring that scans JWT endpoints on a configurable schedule, alerting your team when email injection vulnerabilities are detected in production APIs.
Frequently Asked Questions
Can email injection in JWT tokens lead to account takeover?
Yes, email injection in JWT tokens can lead to account takeover when combined with other vulnerabilities. If an attacker can inject email headers to intercept password reset emails or modify notification emails, they can gain unauthorized access to accounts. The injection becomes especially dangerous when JWTs are used for session management in email-based authentication flows.
How does middleBrick detect email injection in JWT tokens differently than manual testing?
middleBrick uses automated scanning with crafted payloads that test for email injection patterns systematically across all JWT endpoints. Unlike manual testing which might miss edge cases, middleBrick tests multiple injection patterns including newline characters, SMTP commands, and header manipulation attempts. The scanner also analyzes the runtime behavior of JWT processing to detect vulnerabilities that static analysis might miss, providing severity ratings and specific remediation guidance for each finding.