Securing Online Voting

by kr

Introduction

I work as a programmer in a large company (based in one of the European countries) that provides web support for various online campaigns for big domestic and international companies.  We prepare more or less complicated websites, Facebook applications, online forms, etc.

Lately, I got a few assignments to prepare websites for competitions, i.e., an Internet user uploads some image, photo, etc., which is then rated by other people.  The entry with the most votes wins, plain and simple.

In this article, I will share with you some of my experience on securing (and hacking) such applications.

There are many methods to secure voting applications.  None are perfect.  Here's a short list.  (I didn't elaborate on some of the methods, as you may be familiar with them.  If not, visit the websites referred to or Yandex it.)

Overview of Methods

Cookies:  The simplest method (to implement and to evade).  In short, you, as a developer, can save a small text file on the user's computer and read its contents later (at least, if the user is not a paranoiac freak who turned cookies off).  Evading cookies is as simple as turning them off, deleting them, or changing their contents.  This works for some less experienced cheaters.

Recently (September/October 2010), some smart guy developed "Evercookies", an API that tries many different methods of storing the "undeletable" equivalent of cookies.  It's nice, but it doesn't work when you are connecting in a different method, like Curl, or using the "safe" mode in your browser.

CAPTCHA:  This acronym stands for "Completely Automated Public Turing test to tell Computers and Humans Apart."  In other words, it's more or less garbled text displayed to you that you have to retype.  In many situations, it'll help you to avoid people who would like to write automated scripts to do the dirty work, although if your CAPTCHA is lousy, it is easy to read it with some OCR-like script.

If it isn't, there are some Russian folks who would be happy to help you (CaptchaBot - I didn't test them and am not endorsing them in any way; I'm just impressed by their service, and maybe you'll find it useful).  It's still not effective against folks who sit at their computer 24/7 and press "vote" every five seconds and then retype the password (more about that later).

Email Confirmation Link:  The vote would be counted only when the user clicks on the link that is sent to him/her by email.  The main advantage of this method is that the process is more time consuming for the user (so it's a little bit harder to mass vote).

Filtering out illegitimate votes is possible, but needs some knowledge from the perspective of the attacker.  You can block known disposable email addresses like spam.la or 10minutemail.com; you can see if someone tries to use known capabilities of free mail services (i.e., in Gmail, those addresses are connected to the same account: example+something@gmail.com, e.xample@gmail.com, e.x.a.mple@gmail.com, etc.); other evasions can be tracked in the post analysis, i.e., you can see that somebody created a catch-all alias in their own domain, or is using free addresses like john01@yahoo.com, john02@yahoo.com, john03@yahoo.com, etc.).  A more annoying extension to this method is forcing users to register an account on your site.

Facebook Connect:  It's not always a good idea, but sometimes the competition is directed to the Facebook users.  The Facebook user ID is an additional variable that we can take into account (but it is not wise to rely only on that!).

IP Limit:  Limiting one vote per IP (i.e., per day).  It looks like the best idea, but isn't always.

For example, ADSL or mobile providers don't assign their subscribers a fixed IP.  Instead, they can change it every time a connection is established.  A Tor network (www.torproject.org) might be used to change one's IP address every time they wanted.  On the other hand, people in the same network (office, home, or university network) would be unable to vote, even if they were on different workstations, as they are visible on the outside as if they were connecting from the same host.

Browser Fingerprint:  Nice method that you can read about at panopticlick.eff.org and www.networkworld.com/news/2010/051810-eff-forget-cookies-your-browser.html.  It turns out that your browser leaves many traces that, combined into one, allows for a quite unique fingerprint.  As with Evercookies, it's good for non-advanced users using browsers, but completely useless if someone wants to cheat you using Curl or something.

SMS Verification:  O.K., in my opinion this method is the best, but clients don't want to implement it because it's expensive.  The idea is simple - if you want to vote, you have to give your mobile number.  We send you a SMS with some code that you have to use to validate your vote.

The rule is that you can only place one vote per mobile number (i.e., per day, week, or just one and only one).  It's highly unlikely that someone will have many different mobile numbers at his/her disposal.

As you can see, none of the methods is perfect in itself (maybe the seventh is).  My suggestion is to combine some of them and then, as a last resort, add some techniques of analyzing votes after they have been placed.

More on this later.

Case Study

As an illustration of the problem, I'll share with you one of the cases.  It was a project for some big international company, which I will not identify to protect their (and my) business.

The idea for the competition was quite simple - people would upload images on the given subject, and then visitors could vote for the photos they liked most.  The winner would be given quite an expensive prize, worth an equivalent of $3500 or so.  In other words, the stakes were high.  So was the number of people wishing to cheat.

I presented the customer with some recommendations based on the list above.

Unfortunately, they decided to employ the least effective and most vulnerable techniques: protecting by CAPTCHA, cookies, and IP limit.  They didn't want to employ any demanding or expensive methods.  So that was it.  I had no choice.

So there it was on the production server - my application (that I was not so proud about) with weak protection, waiting for some rascals.

It wasn't a big surprise to me when, a day or two after the competition was announced, some of the entries started to gain more votes than the others.  At this point, the battle began.

First, I exported a list of votes per image with their times and IPs.

I ran blocks of IPs through the databases (available online at ripe.net [Europe], arin.net [North America], apnic.net [Asia and Pacific], lacnic.net [Latin America and Caribbean], and afrinic.net [Africa]) to get ISP information for the votes.

It turned out that cheaters were using ADSL or mobile wireless connections that allowed them to change their IP when they reset their modem.  I concluded that they were still typing in the CAPTCHAs manually because the interval between consecutive votes was significant, as well as (which I found quite funny) the fact that voting started at around 8 to 10 am (when they woke up) and ended around 11 pm to 1 am (when they went to bed).

To prevent those guys from voting, I just blocked some IP ranges.  I observed that legitimate voters weren't using mobile networks to vote anyway.

This action caused a big decrease in the illegal votes.

But, a few days later, I noticed some other guy doing funny stuff.  The pattern was the same - lots of votes placed all day with a break for sleep in the night hours.  One thing was different.  IPs were changing all the time, but they weren't from the same network.  They were from all around the world!

Germany, then USA, then Japan, China, some African countries, and so on.  I quickly realized that this guy was using Tor or some similar network.  Fortunately, the rules of the competition were saying that only people in my country were eligible to vote and win.  So I found a database that provided information about the country of origin of every single IP address (Yandex for "IP geolocation free").  Two hours later, every vote from abroad, past and future, was invalid.

In the meantime, I added some more security to the site, making "cookies enabled" a requirement and adding some session variables loaded on the page showing the photo (just before the vote).  It allowed me to cut some of the less experienced cheaters.

For a while I thought that it was over.  But I was wrong.  There was still one guy voting all the time.

He was using a trick with changing IPs all the time and I wasn't allowed to ban his IP range because it was the most popular ADSL provider in my country (ten percent market share).  One thing that I noticed was that he was voting all the time, even in the night.  It was impossible for a living person to do this, so I concluded that he had some script to pass my (lousy) CAPTCHA.  The cure was simple.

I found an open-source script with some more sophisticated, distorted CAPTCHAs and implemented it.  It turned out his skills were not enough to crack it and he was too lazy to type every CAPTCHA for 12 hours a day.

Finally, I won.  It all ended happily.

The grand prize was won by a recently married couple who posted their sweet photo everywhere online and asked people to vote.  One thing that I found significant about this and others' legitimate projects was that, when analyzing sources of their votes (IP blocks), it turned out that they were spread evenly and over a large number of different networks (hundreds of different networks), while votes for cheaters' projects were coming in large quantities from only a few networks.

Conclusion

O.K., so what's the conclusion of this story?

Sometimes, you have limited resources and you can't apply sophisticated techniques to protect your application, but looking into the logs and trying to get into the bad guys' minds can help you to defeat the evil (of course you can "look" into logs in some automated way - that is something I plan to work on, having new experience from these projects).

Return to $2600 Index