mediumCWE-400A05:2021

No Rate Limit on Email/SMS Sending

Email and SMS endpoints without rate limiting can be abused to spam users or drain your sending budget through automated requests.

How It Works

Password reset, verification email, and SMS endpoints that have no rate limit can be triggered thousands of times per minute. Attackers use this to spam victims with unwanted emails, run up your Twilio/Sendgrid bill, or enumerate valid email addresses by checking whether an email is sent.

Vulnerable Code
// BAD: password reset with no rate limiting — spammable
export async function POST(req: Request) {
  const { email } = await req.json();
  const user = await db.users.findByEmail(email);
  if (user) await sendPasswordResetEmail(user); // no rate limit!
  return Response.json({ message: 'If that email exists, check your inbox.' });
}
Secure Code
// GOOD: rate limit by IP and by email address
export async function POST(req: Request) {
  await rateLimit(req, { max: 3, window: '1h', key: `reset:${req.body.email}` });
  await rateLimit(req, { max: 10, window: '1h', key: `reset:ip:${getIP(req)}` });
  const { email } = await req.json();
  const user = await db.users.findByEmail(email);
  if (user) await sendPasswordResetEmail(user);
  return Response.json({ message: 'If that email exists, check your inbox.' });
}

Real-World Example

Multiple services have been abused to send thousands of SMS messages using their own Twilio account by exploiting unprotected SMS sending endpoints. Bills of $5,000-$50,000 in a single day have been reported on platforms without rate limiting.

How to Prevent It

  • Rate limit email/SMS sending to 3-5 per hour per email address
  • Also rate limit by IP address to prevent distributed flooding
  • Set up Twilio/Sendgrid spending limits and alerts to cap potential abuse damage
  • Use CAPTCHA on high-value email endpoints like password reset and contact forms

Affected Technologies

Node.js

Data Hogo detects this vulnerability automatically.

Scan Your Repo Free

Related Vulnerabilities