In summer 2011 issue of the 2600: The Hacker Quarterly magazine I published the article titled “Securing online competitons”. It is based on my experience and features the case study of one of the interesting cases.
Click “Continue…” for the full text of the article.
I work as a programmer in a big company (based in one of the European countries), that provides web support for various on-line campaigns for big domestic and international companies. We prepare more or less complicated websites, facebook applications, online forms, etc.
Lately, I got few assignments to prepare websites for competitions – i.e. internet user uploads some image (photo, some image, etc.), which is then rated by other people. Entry with 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 application – neither is perfect. Here’s short list (I didn’t elaborate on some of the methods, as you may be familiar with them. If not – see the references or google it.)
Overview of methods
- Cookies – simplest method (to implement and to evade). In short – you, as a developer, can save on the user’s computer small text file and read it’s contents later (at least if the user is not paranoic freak who turned cookies off). Evading cookies is as simple as turning them off, deleting or changing their contents. But it works for some less experienced cheaters. Recently (Sept/Oct 2010) some smart guy developed evercookies – API that tries many different methods to store “undeletable” equivalent of cookies. It’s nice, but is not working when you are connecting in the different method, that using web browser (i.e. curl) or use “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 by some OCR-like script. If it isn’t, there are some Russian folks, who would be happy to help you anyway (I didn’t test them or endorse in any way, I’m just impressed by their service – and maybe you’ll find it useful). It’s still not useful against folks, who would sit at their computer 24/7 and press “vote” every five seconds and then retype the password (more about it later).
- E-mail confirmation link – vote would be counted only when user clicks on the link that is sent to him/her by e-mail. 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 e-mail 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 adresses are connected to the same account: [email protected], [email protected], [email protected], etc.); other evasions can be tracked in the post analysis – i.e. you can see, that somebody created catch-all alias in their own domain, or is using free addresses like [email protected], [email protected], [email protected], etc.). More annoying extension to this method is forcing users to register an account on your site.
- Facebook Connect – it’s not always good idea, but sometimes the competition is directed to the Facebook users. Then Facebook user id is 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 not always is. For example, ADSL or mobile providers don’t assing their subscribers with fixed IP, rather change it every time connection is established. TOR network might be used to change one’s IP address every time they want. 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 here and here. It turns out, that your browser leaves many traces that, combined into one, allows to prepare quite unique fingerprint. As with evercookies, good for non advanced users using browsers, but completely useless, if someone wants to cheat you using curl or something.
- SMS verification – OK, in my opinion this method is the best, but clients don’t want to implement it, because it’s expensive. Idea is simple – if you want to vote, you have to give your mobile number. We send you SMS with some code, that you have to use to validate your vote. 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 itself (maybe the 7th is). My suggestion is to combine some of them and then, as a last resort, add some techniques of analysing votes after they have been placed – more on this later.
As an illustration of the problem, I’ll share with you one of the cases. It was project for some big international company, which I will not identify to protect their (and mine) bussiness. 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 like most. Winner will be given quite expensive prize, worth an equivalent of $3500 or so – in other words, the stake was high, so was the number of people wishing to cheat.
I presented customer with some recommendation, based on the list above. Unfortunately, customer decided to employ least effective and most vulnerable techniques: protecting by CAPTCHA, cookies and IP limit. He didn’t want to employ any demanding or expensive methods, to 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 big suprise 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 begins. First, I exported list of votes per image, with their times and IPs. I ran blocks of IP through the databases (available online at www.ripe.net [Europe], www.arin.net [North America], www.apnic.net [Asia & Pacific], www.lacnic.net [Latin America & Carribean] and www.afrinic.net [Africa]) to get ISP information for the votes. It turned out, that cheaters (there were few of them, voting for their own entries, respectively) were using ADSL or mobile wireless connections, that allow to change your IP when you reset your modem. I concluded, that they were still typing in the CAPTCHAS manually, because interval between consecutive votes was significant, as well as (I found it quite funny), voting started around 8 – 10 a.m., when they woke up and ended around 11 p.m. – 1 a.m., 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 big decrease in the illegal votes. But, few days later, I noticed some other guy, doing funny stuff. The pattern was the same – lots of votes placed all day, with break for sleep in 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 realised, that this guy was using TOR or some similar network. Fortunately, rules of the competition were saying, that only people in my country are eligible to vote and win. So I found database, that provided information about country of origin of every single IP address (google for “ip geolocation free”). Two hours later, every vote from abroad – placed in 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’s over – but I was wrong. There was still one guy voting all the time. He was using trick with changing IPs all the time and I wasn’t allowed to ban his IP range, because it was most popular ADSL provider in my country (10% market share). One thing, that I noticed was that he was voting all the time, even in the night. It was impossible to do for living person, so – I concluded – he had some script to pass my (lousy) CAPTCHA. The cure was simple – I found opensource script with some more sophisticated, distorted CAPTCHAs and implemented it. It turns out, his skills were not enough to crack it, while he was too lazy to type every CAPTCHA for 12 hours a day.
Finally, I won. It all ended in happy-end. The grand prize was won by recently married couple, who posted everywhere online their sweet photo and asked 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 large number of different networks (i.e. few hundrends different networks), while votes for cheaters’ projects were coming in large quantities from only few networks, with relatively short tail of other networks.
OK, 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 still looking into the logs and trying to get to the bad guys’ minds can help you to defeat the evil (of course you can “look” into logs in some automated way – that is some thing I plan to work on, having new experience from these projects).