Recently we transitioned from using SendGrid for DropDAV’s email delivery to Mailchimp’s Mandrill. SendGrid’s got a foul smell about it in general these days, and we had approached our send quota for the month too quickly, so switching to Mandrill would give us an instant win by not having to upgrade our SendGrid account’s plan. Happily, switching on Heroku was as simple as adding the Mandrill add-on, changing the SMTP settings in our Rails app1, deploying and removing the SendGrid add-on.
Cruising through all of the numerous Mandrill Control Panel options, we found the ability to email a designated address any time an email sent to one of our users fails for some reason. Curious, I subscribed my email address to the alerts to learn how many, if any, of our emails were bouncing and why.
The bounced/rejected/no-such-user emails started pouring in.
I completely ignored the first handful. And the first few months’-full. Then I decided to read enough of the notification to determine the cause, and possibility attempt to troubleshoot it a bit.
The email address "[email protected]" was refused by the server.
Oh was it? I figured “hahascammedyou666” would have legit multi-MX server failover and whatever.
I went back to all the previous alerts I’d ignored and read them over. There were bunches of clearly intentionally fake addresses intended to shield the user from the terrible pain of receiving email from the service from which they’re deriving value.
I was peeved, and even though all of those people were just getting the same free trial we extend to all of our users, I felt like these fake email address users were stealing something. But I shrugged it off as harmless, and impractical to try to repair until I recognized a pattern in the string of fake addresses:
Oh that one, too? OK, WTF!
Honestly, we naively assumed giving away full-featured free trials of the service eliminated any reason our customers might have to lie about their email addresses.
The unfortunate reality is there exists a class of user that expects something for nothing, and we decided we wanted to take steps to limit their success deceiving our systems and exploiting our good will.
The first, most naive solution, was to add a quick validation to our user model that prohibits users from registering with an email address @dropdav.com. Obviously this solution has an extremely narrow scope of usefulness, but it provided a cheap win that blocked a substantial proportion of the fakers right away, with no added burden placed on legitimate users.
And that was the most important thing for us: placing no additional burden on legitimate users. A key result of our efforts to reduce illegitimate access to the service was that there be zero evidence of our efforts visible to legitimate users.
This meant blanket requirements that all users must click a confirmation link in their email were non-starters2. Even if we gave users a couple days before degrading their quality of service, legitimate users would be burdened under the auspices of reducing illegitimate use. Ideally, we could allow any user to sign up (as long as they didn’t provide an email address @dropdav.com), then weed out the illegitimate email addresses in the background somehow.
Enter Mandrill’s Webhooks. Mandrill can notify a URL you specify whenever an email deliverability event occurs. We already use Stripe’s powerful Webhooks for DropDAV’s payment processing, so integrating Mandrill’s Webhooks seemed like a natural solution.
Now, whenever Mandrill gets a rejection notification from the receiving mail server, or has a message hard bounce, Mandrill will notify a specially designated path on our web server with the details of the incident. Upon receipt, we look up the user account associated with the email address Mandrill provides, and mark the account as having an invalid email address.
When an account is marked as having an invalid email address, the user’s access to the DropDAV WebDAV service is immediately suspended (all requests result 403 Unauthorized). The user needs to log in to DropDAV.com3 where they will be greeted with a red banner at the top of every page informing them that their email address has been flagged as invalid, and that their service is suspended until they supply a new email address.
For now, when they enter a new email address to reactivate their account, we accept any address and do not require them to click a confirm link in their inbox even then when they have been outed as a probably scamster. We’ll closely monitor what goes on there, and may add a confirmation link process for these flagged accounts in the future.
When we decided to integrate Mandrill’s Webhooks, we went looking for a quick way to roll them into our Rails application. We found the excellent mandrill-rails gem, and got Webhooks working with our app in just a few minutes.
The gem didn’t include support for Mandrill’s cryptographic request signatures, so we forked it, wrote in support for verifying the requests, and submitted a pull request that the gem maintainer quickly merged so that all users of the gem can benefit from verifying the Webhook requests are indeed coming from Mandrill. Neat!
We’ll leave the comments open below to discussion about the best ways you all are treating the threat of bad actors amongst your users. As we make changes to our policies, we’ll try to keep this post updated with what we find to be the best practices for weeding out bad users without burdening all users.
You should subscribe to our blog via RSS and follow us on twitter to receive the latest updates from smiles+laughs headquarters.
We could have avoided changing our SMTP settings and deploying by copying the the config values for Mandrill into the previous SendGrid values our SMTP config referenced. Like: $ heroku config:set SENDGRID_USER=
heroku config:get MANDRILL_USER, but that didn’t occur to me until I went to write this.↩
Personally, and as the founder of smiles+laughs, I feel a twinge of insult anytime I’m asked to confirm something for the requester’s benefit. Confirmation links in my email and credit card ZIP code verification at brick-and-mortar checkouts suggest to me that the retailer thinks there’s a greater likelihood than not that their customers are trying to cheat. I really don’t appreciate the insinuation that I’m a cheat; especially at the exact moment I’m transferring my money to the merchant.↩
Ideally we could email the user to alert them that their account has been suspended, but with only their invalid email address to contact them via—no dice. ↩