This Thursday I opened my email to find 20+ unread messages from Twilio. They all had the same subject "Your Twilio account has been recharged".

Oh no.

For some context, I make Luma which helps people host delightful events. As part of the sign up flow, you can link your phone number. When you go through this flow, we text you a verification code. Pretty standard.

When I looked through the logs, I found the attackers were using 20,000 IP addresses to create Luma accounts and request SMS hundreds of thousands of verification codes.

Why would someone want to get a verification code sent to a random phone number? We've seen phishing attacks, but this attack didn't make sense. It was costing us money (texting is expensive!) but what was in it for them?

After some research, I figured out that the attackers were doing SMS Traffic Pumping. SMS Traffic Pumping takes advantage of referral fees offered by some shady mobile network operators. In this scheme, Luma pays Twilio per text, Twilio pays the mobile network operator, and the network gives a kickback to the hacker who attacked us.

The texts that the attacker sent from Luma matched this pattern. The attackers bought blocks of phone numbers which all shared the same prefix. For example, the attackers sent 13k messages to numbers starting with +99899394.

With this context, it was much easier to put in a defense against this attack. We didn't want to introduce CAPTCHAs or anything else that would affect a normal user's experience so we settled on multiple tiers of rate limiting:

  • IP Address — We limit the number of requests by IP address to sensitive routes. Although the attackers worked around this by using many different IPs.
  • User Account — In order to send an SMS verification code, you need to be logged in with a verified email. This can also be gamed with disposable emails, so we discourage signing up with those emails.
  • Geo Blocking — It's very expensive to text some countries. For example, Twilio charges over $0.30 for each text to Uzbekistan. And these countries often use WhatsApp or other messaging apps instead of text. So it makes sense to limit SMS to countries with lower fees and higher SMS penetration.
  • Phone Prefix — Attackers often purchase blocks of phone numbers at a time. So if we see a lot of texts going to the same number block, that's very suspicious. We rate limit the amount of texts going out to each prefix.

This has put us in a pretty good solution and hopefully it'll help some other people defend against these attacks.

Twilio is in an interesting position. I'm sure that if they were dedicated to it, they would be able to stop this kind of fraud. But it's leading to a lot of extra revenue for them...