Lately I noticed an increase in ‘empty’ sign-ups for Productific: new users join but they do not create a product listing. While there is always room for improvement in the onboarding flow, the large number of empty sign-ups made me suspicous. Signing up for a roadmap voting tool without even listing a product just doesn’t make any sense. Once I noticed that many sign-ups to not appear in Google Analytics stats (which is running via javascript in the client browser) it was obvious: there is an increase in SPAM sign-ups. Automated scripts are flooding Productific’s sign-up form with dummy accounts. The business mechanics behind this are unclear (any ideas? please comment), yet these fake sign-ups hurt my service in various ways:
Email reputation
While the sign-ups are obvious fake, the actual email addresses appear to be real. So any confirmation email send to these addresses will be -correctly- regarded as SPAM and hurt Productific’s email reputation.
Email cost
While the sign-ups are obvious fake, the actual email addresses appear to be real. So any confirmation email send to these addresses will be -correctly- regarded as SPAM and hurt Productific’s email reputation.
Sign-up metrics
User metrics are polluted by fake sign-ups. Filtering these in all analysis is extra work, ideally fake accounts should not appear in user metrics.
That pain must stop.
Counter measures
So I took the decision to block sign-up SPAM. The obvious choice is to introduce a captcha. Adding such a captcha would require my users to confirm that they are not a bot. Sometimes this is just a simple checkbox, sometimes they will be presented a short test to solve in order to prove they are not a bot. While it is an appropriate measure against fake sign-ups I do not want to put that burdon on my onboarding flow.
Digging a little deeper I analyzed the bot’s behavior and weakness. I introduced the following automated counter measures which can successfully block fake sign-ups.
Trick #1: measure sign-up time
Bots are fast. They do not type a username and password, they automatically fill the form fields and submit their data. This is efficient to them but also reveals their true objectives. A human user would always take a few seconds to type username/password on a keyboard, the least a human would pull account info from Google/Apple’s keystores which also takes a moment. Hence, any sign-up that happens with zero time in the browser or with only a few milliseconds between page load and sign-up form submit is a bot.
To measure sign-up time you can simply post a getTime() in server.render() or client.ready() and post the time elapsed since page load in a hidden form field. Submit that time elapsed to your backend and handle with appropriate care…
Trick #2: the honeypot
Some bots blindly fill all the fields in a sign-up form. So I added a ‘honeypot’ username field, next the email address required, which the system is hiding via CSS. Bots which do not evaluate CSS will see this field and submit a username to sign-up, while human users will not see that field and not submit a user name. Just post that username to the backend, any sign-up with the ‘honeypot’ user provided must be a bot.
Putting things in perspective: both tricks can be easily be bypassed by bots. Once someone has resources and willingness, these counter measures can be avoided by a bot. Adding a wait and avoiding a honeypot field is simple and easy. However, to actually bypass these counter measures a bot enhancement individual to my sign-up form is required — which represents real work to the bot owner. SPAM bots are rather moving elsewhere.
Summary
The obvious choice for blocking fake sign-ups is a captcha. But captchas dilute the onboarding experience. To avoid that burden for my users and maintain a lean onboarding experience I use the sign-up time and a honeypot field to automatically identify and flag sign-up bots. With two simple enhancements Productific is relieved of the sign-up SPAM pain — no captcha required.
Top comments (1)
Is it still relevant?