How to setup your Twilio account to stop and avoid Twilio Toll Fraud
AI-generated TL;DR
- Twilio Toll Fraud Risks: Twilio users face the risk of toll fraud, where bad actors inflate usage by sending excessive SMS log-in codes, especially to high-cost international numbers, potentially leading to significant unexpected costs.
- Inadequate Default Protections: Twilio’s default settings and features like Verify Fraud Guard are insufficient in preventing fraud, as evidenced by cases where large numbers of fraudulent texts were sent before protective measures were activated.
- Preventative Measures: To combat Twilio toll fraud, it’s recommended to customize Twilio settings (e.g., blocking international numbers), enable maximum protection with Verify Fraud Guard, set usage alarms, use captchas, implement two-layered authentication, and potentially use additional infrastructure defense like Cloudflare.
Introduction
Twilio, the phone and video toolkit, is like dynamite — both powerful and dangerous.
You should take caution with any metered API since every last request will cost you.
But exposure runs higher with Twilio:
- According to Twilio, bad actors have an incentive to inflate your usage through what’s called Toll Fraud.
- Thanks to features like Twilio Verify, they also have a means to do so: by repeatedly asking for SMS log-in codes. As you may realize, you don’t have to have an account to request a code, so fraudsters can elude auth restrictions.
- And texts sent to phones in certain countries can run you 2,400% more than domestic texts. In other words, just
four40 attempts could cost you the price of 1,000 messages. Things add up fast. - Twilio settings alone don’t protect you. Take their feature Verify Fraud Guard: we’ve seen it fail to kick in for hours of anomalous requests.
So let’s drill into the Twilio liability: why it exists, the basic steps you should take to protect yourself, and the custom software guards that we recommend. If you have a question about your Twilio set-up, feel free to reach out.
Twilio Toll Fraud
Why would someone want to trick your app into blasting texts and calls into a void?
Junk or not, traffic generates revenue for wireless carriers. According to Twilio, some carriers share cash with entities that direct usage. So taking a step back:
- You pay Twilio for usage
- Twilio pays the carrier for the traffic
- The carrier, in turn, might pay a share to “referrers”
Thus bad actors can take home some of the “proceeds” from your eye-watering bill.
A real Twilio fraud pump
Now let’s look at some real data.
A client with a mobile app woke up to a slew of emails from Twilio that marked debits to the account. They racked up about $800 in a few hours; while not life-ending, this sum exceeded 10x their bill from the previous year.
Sure enough, nearly all of usage spawned from Twilio Verify messages, those texts with log-in codes.
Our client’s account had enabled a feature called Verify Fraud Guard, a Twilio service meant to detect and block sketchy Verify requests. Verify Fraud Guard is a bit of a black box: Twilio doesn’t broadcast what trips an alarm, they only provide false positive rates. Our client kept the default setting “Standard Protection”.
It turns out that Verify Fraud Guard did eventually kick-in, only after 2.5 thousand bogus texts. It blocked the next 4 thousand.
As you can see, messages went all over the world. Not so coincidentally, they went primarily to phone lines with exorbitant rates; Indonesia phone numbers, for example, run about $.36 per message. That’s over 50 times more than what it costs to send a message in the US.
Moral of the story: toll fraud happens quickly and effectively on Twilio accounts with default settings.
Billy Chasen did an excellent write-up of another Twilio Toll Fraud attack.
Recommended Twilio settings
Part of the solution is to beef up your default Twilio settings.
Country settings
Is your platform local? Is it feasible to block use outside your country?
K-Optional Software builds mostly for the US market, so we often advise clients to disable calls and texts to lines outside of North America. In doing so, we block fraud in three ways:
- American carriers don’t support the cash-sharing scheme described by Twilio. So we reduce the pool of attackers from thieves and vandals to just vandals.
- SMS messages sent to “+1” numbers cost just $.007 per segment; at that rate, it would take 150 thousand segments to ding you $1,000. Due to sending bottlenecks, that could take over a day.
- We slash the pool of numbers that one could even use.
By default, Twilio leaves all country codes unblocked. We tell folks to first switch all of them off and enable those needed one by one. An “opt-in” mindset is the low-hanging fruit of Toll Fraud protection.
Verify Fraud Guard
If you use Twilio Verify, you should enable Verify Fraud Guard. We would recommend the “Max Protection” setting based on our client’s experience, rather than the default “Standard Protection. We risk more false positives, but in practice that hasn’t been an issue for us.
Find Verify Fraud Guard under Develop >> Verify >> your verify service >> SMS.
Alarms
Alarms tell us that something happened: the clock just hit 7, there’s smoke in the building, we’ve racked up a big bill.
In the context of Toll Fraud Protection, we can set usage-based alarms. On Twilio that could mean:
- Your account has sent more than 1,000 texts.
- Your spend now exceeds $100 today.
Alarms mostly can’t hurt. Except when you hear so many of them that you tune them out. So be careful to set alarms sparingly; all should warrant concern.
Twilio recommends using alarms. But a Twilio alarm won’t fix the problem any more than a smoke alarm puts out a fire. I’m inclined to think alarms can give the illusion of security. In the case of our client, alarms did sound… in the middle of the night to an unchecked inbox. Yes, there are ways to make alarms more invasive, and it’s a good idea to use them. But we say to reach for more active strategies.
Custom Software approaches
The kill switch
Pay-per-use APIs like Twilio tend not to support “usage caps.”
But with custom software, one can craft a kill-switch. Say you know you will never need to spend more than $100 in a day — your code can turn off sending when you reach that point, like a robot unplugging itself.
Consider that this approach trades one weakness for another: you’re safe from a bill without a ceiling, but might be on the hook for some down-time. You may not want to make that trade-off.
One can make a Twilio kill-switch with code that checks for usage and deletes the Messaging Service when in excess. Like a blown fuse, it requires downtime until someone manually replaces it.
Otherwise, you can tuck all Twilio logic into a code block that’s aware of usage status, quickly exiting when above some threshold.
Captchas
Our goal is to block fraud, ideally leaving real users unbothered.
What we need is a way to tell the two apart. Maybe we can force users to help ID themselves?
Consider how fraud differs from real use:
- A real user interacts with an app, resulting in a modest amount of requests.
- Toll Fraud attackers blast an app over a small time frame. They use scripts or spam forms by hand.
Is there a way to tell the two apart?
Enter Captchas, those pervasive and annoying checks that ask “are you a robot?” By taxing every use with a slow, manual chore we can make Toll Fraud a fool’s errand.
As much as we all hate Captchas, they are likely the closest thing to a silver bullet for Twilio Verify fraud. And Captchas first try to vet you without asking which photos feature a bus; they resort to those checks only when your interaction patterns aren’t clearly human.
When it comes to SMS-based login, there’s one case where you might not need something like a Captcha…
Two-layered auth
If you can ID the man or machine using your app, then the specter of Toll Fraud fades. After all, we would be able to apply a rule such as: “each account may not exceed 30 requests per minute or 300 per hour.” An earnest user likely won’t ever touch this type of rate-limit.
Why won’t that work for anonymous visitors? Couldn’t we just define limits per device? Yes, that’s an option (stay tuned), but one person can use many machines. And that they do: hackers employ botnets to mount attacks from devices all over the globe.
So back to identifying users… to achieve this, you might use SMS-based verification codes, the very process that fraudsters exploit.
Is it possible to vet a request before sending a message at all?
Finite userbase
We sometimes build apps meant to be used solely by one organization. Therefore, we might know all phone numbers that should be able to sign up or log in. The system can reject log-in attempts from outsiders. Voila, no need to risk sending bogus texts.
Admin-approved users
Even if you don’t have an immutable list of users — which I admit is rare — you might be able to tell if someone belongs. A lot of B2B apps use some sort of admin-vetting process. It could look like this:
- Someone joins an organization
- An admin adds this person to the system
- The system allows this person to log in
We see this approach quite a bit in back-office custom software. The trick then is to vet the phone number trying to gain access prior to sending any messages.
If I see someone asking for a log-in code, and the phone number they provide is not on our whitelist, I will skip sending them a code. They wouldn’t have been able to use the service anyway, and we block the anonymous vector for fraud.
Note: you likely want to be subtle when screening a number; telling someone “you’re not in our system” might allow them to see what phones are in your system.
Insider information
Other systems have neither have a set list of users nor a screening process. We can still reduce the footprint for spam and fraud if we can check an extra data point.
Some examples:
- Do people need to be in a certain place to use your app? You can collect device location and block attempts outside of an area. Since one can spoof coordinates, we advise not to reveal whether their request was successful.
- Is it possible (and not unsightly) to ask users for an extra data point when logging in? For instance, one of our clients asks users to enter their employee ID number when logging in.
Infrastructure defense against Toll Fraud
Cloudflare
You might consider delegating fraud protection to a provider like Cloudflare, which can stop bad actors from even accessing your site, much less abusing your SMS integration.
Here are some benefits to this approach:
- Fraud protection on the web is an economy of scale, so a big player will be proportionally more equipped.
- Cloud proxies like Cloudflare can work for about every type of app, whereas custom code depends on the details.
- A cloud proxy will protect your entire server, not just your Twilio pathways. That means absorbing strain on the system.
To use Cloudflare, your domain name must reside on the service, which may be a drawback for some.
If you can use the service, the following two Cloudflare tools will come in handy.
Web Application Firewall (WAF)
Cloudflare’s Web Application Firewall (“WAF”) Settings support “rules” that can help stop Toll Fraud attacks. Here are some rules you can
- Apply rate limits like “No more than 10 requests per minute from one IP”
- Block requests that Cloudflare deems “likely automated”
- Block requests that seem to be from some country
- Block requests with a high Threat Score. Cloudflare assigns this score based on an IP’s history of spam requests.
Automatic DDoS Protection
You get HTTP DDoS Attack Protection for free by virtue of having a domain on Cloudflare. This might kick in during a Toll Fraud attack, depending on the scale.
Automatic DDoS Protection can even foil major botnet attacks, which can elude IP-based WAF rules.
Concluding thoughts
A strong defense against Toll Fraud combines judicious settings, good infrastructure, and custom software. It’s possible to block bad actors while leaving earnest users none the wiser.
Twilio is a great tool. If you choose to use it, you shouldn’t need to pay the Toll Fraud toll.