Best method to prevent gaming with anonymous voting - php

I am about to write a voting method for my site. I want a method to stop people voting for the same thing twice. So far my thoughts have been:
Drop a cookie once the vote is complete (susceptible to multi browser gaming)
Log IP address per vote (this will fail in proxy / corporate environments)
Force logins
My site is not account based as such, although it aggregates Twitter data, so there is scope for using Twitter OAuth as a means of identification.
What existing systems exist and how do they do this?

The best thing would be to disallow anonymous voting. If the user is forced to log in you can save the userid with each vote and make sure that he/she only votes once.
The cookie approach is very fragile since cookies can be deleted easily. The IP address approach has the shortcoming you yourself describe.

One step towards a user auth system but not all of the complications:
Get the user to enter their email address and confirm their vote, you would not eradicate gaming but you would make it harder for gamers to register another email address and then vote etc.
Might be worth the extra step.
Let us know what you end up going for.

If you want to go with cookies after all, use an evercookie.
evercookie is a javascript API available that produces
extremely persistent cookies in a browser. Its goal
is to identify a client even after they've removed standard
cookies, Flash cookies (Local Shared Objects or LSOs), and
others.
evercookie accomplishes this by storing the cookie data in
several types of storage mechanisms that are available on
the local browser. Additionally, if evercookie has found the
user has removed any of the types of cookies in question, it
recreates them using each mechanism available.
Multi-browser cheating won't be affected, of course.

What type of gaming do you want to protect yourself against? Someone creating a couple of bots and bombing you with thousands (millions) of requests? Or someone with no better things to do and try to make 10-20 votes?
Yes, I know: both - but which one is your main concern in here?
Using CAPTCHA together with email based voting (send a link to the email to validate the vote) might work well against bots. But a human can more or less easily exploit the email system (as I comment in one answer and post here again)
I own a custom domain and I can have any email I want within it.
Another example: if your email is
myuser*#gmail.com*, you could use
"myuser+1#gmail.com"
myuser+2#gmail.com, etc (the plus sign and the text after
it are ignored and it is delivered
to your account). You can also include
dots in your username (my.user#gmail.com). (This only
works on gmail addresses!)
To protect against humans, I don't know ever-cookie but it might be a good choice. Using OAuth integrated with twitter, FB and other networks might also work well.
Also, remember: requiring emails for someone to vote will scare many people off! You will get many less votes!
Another option is to limit the number of votes your system accepts from each ip per minute (or hour or anything else). To protect against distributed attacks, limit the total number of votes your system accepts within a timeframe.

Different approach, just to provide an alternative:
Assuming most people know how to behave or just can't be bothered to misbehave, just retroactively clean the votes. This would also keep voting unobtrusive for the voters.
So, set cookies, log every vote and afterwards (or on a time interval?) go through the results and remove duplicates based on the cookie values, IP/UserAgent combinations etc.
I'd assume that not actively blocking multiple votes from same person keeps the usage of highly technical circumvention methods to a minimum and the results are easy to clean.
As a down side, you can't probably show the actual vote counts live on the user interface, or eyebrows will be raised when bunch of votes just happen to go missing.

Although I probably wouldn't do this myself, but look at these cookies, they are pretty hard to get rid of:
http://samy.pl/evercookie/
A different way that I had to approach this problem and fight voting fraud, was to require an email address, then a person could still vote, but the votes wouldn't count until they clicked on a link in the email. This was easier than full on registration, but was still very effective in eliminating most of the fraudulent votes.

If you don't want force users to log, consider this evercookie, but force java script to enable logging!
This evercookie is trivial to block because it is java script based. The attacker would not likely use browser, with curl he could generate tousends of requests. Hovewer such tools have usually poor javascript support.
Mail is even easier to cheat. When you run your own server, you can accept all email addresses, so you will have practically unlimited pool of addresses to use.

Related

Secure voting system with php without login

Is there a way to make a reasonably secure system to vote without having to login. I now use cookies to set if the person has voted yet and also insert the users ip in the database.
If that user removes his cookies, he will be able to vote again. That's why I do a check if the user's ip exists in the database and if that IP has voted in the last 30 seconds. That way he'll have to remove his cookies and change his IP address to vote again.
I know there's no 100% failproof solution to this, but
is there a more secure way to do this?
There are two ways that could improve your results, but read and judge for yourself, if you need them:
More persistent cookies
There is the Evercookie project, which stores cookie-like information in a lot of places. It is much harder to delete than just normal cookies.
I personally think that this project should be considered a proof of concept and actually using it would be unethical
Better user recognition
Instead of just looking at the IP address in order to identify a returning visitor, you could use Browser fingerprinting. The EFF has shown with their Panopticlick project, that the combination of Browser version, OS version, installed add-ons etc. is often unique. The Piwik web analytics tool also uses this kind of user heuristics to tell visitors apart. I don't know the implementation, but it's FOSS and in PHP, so you should be able to find that part.
You can run with both of those solutions in unison - but it's still not very secure. You could go as far as blocking a subnet from voting (192.168.1.xxx) to prevent against dynamic IP changes, but then you're also blocking up to 254 people from voting - and it won't prevent against a proxy.
One method I've seen used quite a bit is making it look like you allow duplicate votes; i.e: show it on the end user's end that their duplicate vote has been counted, but don't actually count it in your own database.
But realistically, a login system is about the only relatively "secure" way of doing this - but if someone is determined enough, that can obviously be gamed too.
Hope this helps.
Eoghan
You could ad the
User agent (on short periods there's often little chance that 2 surfers have exactly the same : https://panopticlick.eff.org/index.php?action=log&js=yes)
But again ' if someone is determined enough, that can obviously be gamed too.'

Prevent double voting

I'm creating a web application where users will vote for some candidates by clicking thumbs up or thumbs down, and these users won't have any account on the site.
What is the best technique to use? Is it necessary to use captcha for more protection from spam?
Vote counts are expected to be millions, and the subject is not very critical as long as I get 95% accuracy that would be fine. Thanks.
You can combine these two methods:
Add a cookie to prevent multiple votes from the same machine
Log IP addresses and prevent voting more than a set number of times from the same address (for example, 5 times the same hour).
This will make it possible for multiple persons to vote from the same network but still prevent excessive cheating.
You may also make it harder to build a voting bot by adding some hidden form field with a token that must be included in the vote, and/or use Ajax for the voting. I know it's relatively easy to build a bot anyway but most cheaters aren't that smart.
Cookies and Session Ids will help, although both can be lost when the browser is closed (if the user has it enabled to delete them). Still, they will give you some degree of accuracy (ex. the lazy voters won't bother to close and reopen their browsers).
Using IP Addresses would also work, but as #Michael Dillon said people on the same IP address (same router) will not be able to vote.
You have several options, some or all of which you can use.
You can record IP and then check against IP, but then this isn't indicative of a specific person just a computer and sometimes not just a single computer.
You can also write a cookie to a user's browser but a user can use a different browser, machine etc.
Within a user's session you could create a session variable, although if you are expecting very high traffic this may not be the best option, and also only prevents re-voting within the same session.
If you are contemplating a captcha, you may as well ask the user to supply an email address and then you are assured of at least one vote per email address. However, even then you cannot be guaranteed valid email addresses.
You can ask their phone numbers when they want to vote and send to them one time password and use that as verification.
Some my also vote from another numbers but i think this is the most accurate way.

Tracking Computers in an Online Game

So i am running into a problem with people making multiple accounts to make there account better with more resource in game.
So my dilemma is, Many users go thru proxys or NATd info so some legimated users would be banned if i only have 1 user per ip.
Is there a way (with Javascript and PHP) to Get a uniq identifier specific to a computer (without Hardware changes, computer hardware change probably would change the identifier).
Any idea or comments would be much appericated
(The following was revived from a response made by Paul, but deleted by another for being out of place.)
I cant change the client to much because its a browser based game so getting the hwid would be possible. But how with JS or PHP.
Adding timers and restrictions to prevent transfers are in place but doesnt stop them entirely there is an option to email for an IP exception. but that is slow an tedious. Im wondering if there is a definitive to generate a specific id or identifier for a specific computer (Not ip based) that would make it so multiple accounts cant be logged in from the same computer but can be logged in from the same ip
As we are talking about a different account, probably on a different IP and client, you cannot easily find out clone accounts.
You can go for two more heuristic and gameplay options
As suggested before (by #dqhendricks), divide your resources and implement your sharing etc in such a way that you can't easily help your other account with every new account. Make finding other accounts in the beginning hard/impossible, make shareable resources a higher level feature etc. Downside is that this changes the gameplay, it doesn't have to be desireable.
You can perform heuristics on behaviour. There can be specific behaviour that is unwanted: only interaction with 1 other account etc. You could tweak some of the variables etc, but you could easily see suspicious behaviour. Make some sort of 'balance' calculation. Most ingame interactions have some sort of balance. Ofcourse, better players may have a good deal because they know more, or the other way around: they make a bad deal to help smaller players. But when one player only gives and never takes, it's "helping" without acutally playing itself: that might mean it's a clone
Everything with ip-adresses or client-information ($_SERVER) etc is worthless in this case as far as I'm concerned..
You could prevent multiple logins on the same Account (username/password).
If the issue is that they make multiple accounts with many different email addresses etc... and new usernames and passwords then you might be able to do it with Cookies for example that use a unique hardware id and then you simple check that not more than one account is active at any one time based on this hwid. if the hardware changes it doesnt matter as it is relative.
To clarify if the HW id for the first login is 1234 then the second login with generate the same hwid. If you check the cookies or your database (doesnt matter where you store it) for the same hwid then you know its already logged in.
If the hardware changes it doesnt matter as they will still both generate the same hwid.
If they use two computers though the haardware id will be different and this will work.
{sharable resources} = {total resources} - MAX(({starting resources} - {spent resources}), 0)
make only non-starting resources sharable, or maybe make sharing resources an ability you don't gain until level x.
Preventing spoofed/duplicate accounts (while ensuring all legitimate accounts work) is a very difficult task -- for reasons laid out by others. In addition to trying to guard against concurrent multiple accounts, one must guard against non-concurrent multiple account usage.
The core issue isn't so much in determining where an account connected from, but being able to trust that a user only has one account -- and to this end the only "real" solution is to use a system which already provides this sort of information, such as a credit card or paypal account ;-) That is, simply prevent someone from creating a new account (although an account can have multiple aliases/profiles, but these can be trivially tracked) unless they can prove "uniqueness".
(Also consider that two people may have two different accounts on the same machine.)
Happy coding.
I run an online game server aswell. To prevent your dilema, either modify the game client to read the MAC Address, and only allow 1 account per computer. Or log the ip's and only allow the resources to be given to that ip twice.
3rd option: Don't allow transfering of materials from the same ip addresses
4th option: Add a timer on the transfering of resources, make them wait 10 minutes of gameplay before they can do anything like getting rid of the items for others to get

Hunting cheaters in a voting competition

Currently we are running a competition which proceeds very well. Unfortunately we have all those cheaters back in business who are running scripts which automatically vote for their entries. We already saw some cheaters by looking at the database entries by hand - 5 Star ratings with same browser exactly all 70 minutes for example. Now as the userbase grows up it gets harder and harder to identify them.
What we do until now:
We store the IP and the browser and block that combination to a one hour timeframe. Cookies won't help against these guys.
We are also using a Captcha, which has been broken
Does anyone know how we could find patterns in our database with a PHP script or how we could block them more efficiently?
Any help would be very appreciated...
Direct feedback elimination
This is more of a general strategy that can be combined with many of the other methods. Don't let the spammer know if he succeeds.
You can either hide the current results altogether, only show percentages without absolute number of votes or delay the display of the votes.
Pro: good against all methods
Con: if the fraud is massive, percentage display and delay won't be effective
Vote flagging
Also a general strategy. If you have some reason to assume that the vote is by a spammer, count their vote and mark it as invalid and delete the invalid votes at the end.
Pro: good against all detectable spam attacks
Con: skews the vote, harder to set up, false positives
Captcha
Use a CAPTCHA. If your Captcha is broken, use a better one.
Pro: good against all automated scripts.
Con: useless against pharygulation
IP checking
Limit the number of votes an IP address can cast in a timespan.
Pro: Good against random dudes who constantly hit F5 in their browser
Pro: Easy to implement
Con: Useless against Pharyngulation and elaborate scripts which use proxy servers.
Con: An IP address sometimes maps to many different users
Referrer checking
If you assume that one user maps one IP address, you can limit the number if votes by that IP address. However this assumption usually only holds true for private households.
Pro: Easy to implement
Pro: Good against simple pharyngulation to some extent
Con: Very easy to circumvent by automated scripts
Email Confirmation
Use Email confirmation and only allow one vote per Email. Check your database manually to see if they are using throwaway-emails.
Note that you can add +foo to your username in an email address. username#example.com and username+foo#example.com will both deliver the mail to the same account, so remember that when checking if somebody has already voted.
Pro: good against simple spam scripts
Con: harder to implement
Con: Some users won't like it
HTML Form Randomization
Randomize the order of choices. This might take a while for them to find out.
Pro: nice to have anyways
Con: once detected, very easy to circumvent
HTTPS
One method of vote faking is to capture the http request from a valid browser like Firefox and mimic it with a script, this doesn't work as easy when you use encryption.
Pro: nice to have anyway
Pro: good against very simple scripts
Con: more difficult to set up
Proxy checking
If the spammer votes via proxy, you can check for the X-Forwarded-For header.
Pro: good against more advanced scripts that use proxies
Con: some legitimate users can be affected
Cache checking
Try to see if the client loads all the uncached resources.
Many spambots don't do this. I never tried this, I just know that this isn't checked usually by voting sites.
An example would be embedding <img src="a.gif" /> in your html, with a.gif being some 1x1 pixel image. Then you have to set the http header for the request GET /a.gif with Cache-Control "no-cache, must-revalidate". You can set the http headers in Apache with your .htaccess file like this. (thanks Jacco)
Pro: uncommon method as far as I know
Con: slightly harder to set up
[Edit 2010-09-22]
Evercookie
A so-called evercookie can be useful to track browser-based spammers
Have you tried to do browser fingerprinting?
Check this open source from EFF:
https://panopticlick.eff.org/
Could be used to identify one person similar to 500-1500 in the world (!).
You may add captcha to voting form. Also requiring e-mail confirmation will be useful
If you're really worried about it then you have to do something like email verification, which might be sufficient to block most cheaters.
Also it depends whether multiple people behind a NAT are likely to want to vote for the same option (e.g. favourite school).
Any scheme you create can be gamed.
EDIT: As everyone else has suggested, you can use a CAPTCHA such as reCAPTCHA to block automated bots, and make humans less likely to repeat vote. At the cost of making humans less likely to vote at all.
The Vote to Promote pattern (you may be aware of it) has a section on how to mitigate against gaming - but it is a tricky one to avoid altogether. Given your actions to date I would consider using weighting, for example consider a reasonable level of voting over a time period, say 10 votes per ting per hour (just an example not a guide) and for surplus votes weight the next 10 at 90% (ie only count 9), the next 10 at 80% and so on. This is Yahoo's advice on gaming within this pattern:
Community voting systems do present a
number of challenges. Particularly the
possibility that members of the
community may try to game the system,
out of any number of motivations:
malice - perhaps against another member of the community and that
member's contributions.
gain - to realize some reward, monetary or otherwise, from
influencing the placement of certain
items in the pool)
or an overarching agenda - always promoting certain viewpoints or
political statements, with little
regard for the actual quality of the
content being voted for.
There are a number of ways to attempt
to safeguard against this type of
abuse. Though nothing can stop gaming
altogether. Here are some ways to
minimize or hinder abusers in their
efforts:
Vote for things, not people. In keeping with Yahoo's general strategy,
don't offer users the ability to
directly vote on another user: their
looks, their likeability,
intelligence, or anything else. It's
OK for the community to vote on a
person's contributions, but not on the
quality of their character.
Consider rate-limiting of votes.
o Only allow the user a certain number of votes within a given
time-period.
o Limit the number of times (or the rate at which) a user votes
down a particular user's content. (To
prevent ad-hominem attacks.)
Weigh other factors besides just the number of votes. Digg, for
instance, does not calculate their
Digg-score solely on the number of
votes a submission receives. Their
algorithm also considers: "story
source (is it a blog repost, or the
original story), user history, traffic
levels of the category the story falls
under, and user reports." They update
this algorithm frequently. Consider
keeping the exact algorithm a secret
from the community, or only discuss
the factored inputs in general terms.
If relationship information is available consider weighting user
votes accordingly. Perhaps prohibit
users with formal relationships from
voting for each other's submissions.
While this is currently a popular
pattern on the Web, it is important to
consider the contexts in which we use
it. Very active and popular
communities (Digg is an excellent
example) that enable community-voting
can also engender a certain negativity
of spirit (mean comments, opinionated
cliques, group attacks on 'outlier'
viewpoints).
Check out Asirra: http://research.microsoft.com/en-us/um/redmond/projects/asirra/
It's still in beta, but it's pretty cool.
To prevent the bots from voting you can use CAPTCHA.
The only thing that comes to mind is using a Captcha. Either an elaborate one with pictures and noise like the ReCaptcha service, or a very simple and unobtrusive one like "What is seven plus three?" or (If you're located in the US), "What is the last name of our President", simple common sense questions everybody can answer. If you change them often enough, this could even be more effective than a classic image-based CAPTCHA.
CAPTCHA's aren't a silver bullet, the user could have their script display the CAPTCHA to them and solve them manually for at least several votes per minute.
You need to use them in combination with other techniques mentioned here.
You could add a honeypot field like in Django. Most likely, this will not protect you from cheaters who deliberately want to change your competition, but at least you will have lesser 'drive-by' spammers to additionally take care of.
Sorry for the double post, but I wasn't allowed to post two URLs in the same post...
If you're looking at building your own tracking, maybe this link might provide some inspiration: https://panopticlick.eff.org/
Turns out that a lot of browsers can be uniquely identified, even without any form of tracking cookies. I'm guessing a vote-bot might give a very specific fingerprint?
So if everyone ever wants to make a competition where people can win something and wanna use a community driven rating system... here i share some experiences:
The bad:
1) First it cant be made secure for 100%
2) to reach a mass of users which filters out all the nonsense ratings is very hard
3) Forget about star ratings in that case... their is always either 5 Stars or 1 Star
The good
1) Dont give them orientation about where they stand... We replaced the "Order by place" view with a random presentation of the TOP 100 (only the top 30 wll win a price)... This really helped because a lot of users lost their interest as soon as they didnt see where they stood.
2) Don't allow votings like: 1x5_Stars 40x1_Star... Just allow users which vote in a fair way...
3) Most of them act a little bit stupid... You'll see them in your logs and can trace down who votes fair and who unfair... Search for patterns...
**GOOD LUCK ;-) **
CAPTCHA is always good, might be "disturbing" for some users though.
reCAPTCHA is a fairly used service
How about only allow users who logged in with openid and with reCaptcha before submitting the vote, and monitering the submitter list with same ip address.
We use a combination of CAPTCHA and email. The user receive a link with a GUID by mail.
This one must be unique for each user that try to vote.
www.votesite.com/vote.aspx?guid=.....
By using this link the vote is confirmed or not. In database we check the combination of email address and GUID to be unique.
I use a combination of CAPTCHA, IP verification and LSO (Flash Local Shared Objects, hard to find and delete for common people).
1.Use recaptcha
2. Yes randomize your voting options but not like this:
-> from vote_id_1 to asdsasd_1, grdsgsdg_2,
Instead use session variables to set a mask from vote_id_1 to asgjdas87th2ad in the vote form.
What about some post hoc stochastic analysis, like time series analysis - looking for periodicity in events of particular (ip, browser, vote)? You could then assign probability to each such group of events that it belongs to 1 person and either discard all such groups of events beyond some probability level, or use some kind of weighting to lower the weight according to the probability.
Look in R, it contains A LOT of useful analysis packages.
Check the domain details of the email they are using. I had the same problem and found that all of them were registered to the same registrant. I wrote it up here: http://tincan.co.uk/659/news/competition-spammers.html
Now, I filter on the DNS information for the email used in the registration.

Setting up a secure polling system

I'm currently in charge of setting up a polling system (using PHP).
Now for it to be as secure and objective as possible, it's important that a visitor can only vote once. I'm thinking of validating the polls by visitor's IP (there can be only one vote from one IP), and maybe throw in a captcha test to be sure that no bots can get in once they've passed the IP validation for some reason.
So there it is, unique-IP validation and captcha. But is this enough ? Is there a possibility that a single user can change his/her IP by using proxies or other ways I don't know of, and vote multiple times with unique IPs ?
Are there better ways to do this ? Preferably without the captcha.
Thanks in advance.
There is absolutely no way to be sure a user has voted once when it's a public voting system, where no login is required.
Checking the IP is not a good idea for several reason. As described in other answers, lots of networks are behind one ip, and users can just use an other pc with different ip and vote again.
OpenId
Use OpenId to identify the user and check if they have already voted.
Register users
Optionally you could allow users to register themselves if they do not have an openid account.
To implement a secure system, where session spoofing, and thus multiple voting, is made difficult read this
You can't create a 100% secure voting system.
If it's based on registration/IP/cookie, the user can create a new user/get an another PC/delete all cookie.
But you can try it with auto prefilter + administrator as postfilter workflow:
Prevent multiple voting with cookie (or IP / browser properties / etc.) filtering automatically.
On an admin view, the administrator can parse and delete votes by hand based on IP or subnet address. This is nor a perfect solution, but with some good query (same votes in the same time intervall from the same IP/subnet) the administrator can easily delete suspicious votes.
One big drawback of this solution is the need of an administrator. But - I think - there is no perfect solution.
Unless you're going to require identity verified by CA, there is no way you can be sure, that each person votes only once. This of course would be total overkill, so the real question is: how to make multiple votes more difficult.
email with verification code. IMHO overkill, but depends on how sure you want to be.
use session to check who voted. Obviously not 100% secure, but will stop 99% of ppl.
use cookie to check who voted. Like above, some ppl will know how do delete cookies.
use POST, ignore GET.
use combination of 2 or 3 of above.
If you're going to use IP for validation, do not use just REMOTE_ADDR, combine with whole X-Forwarded-For. This way you won't block people connecting through same proxy.
Don't go with the way of unique Ip. There are a lot of case scenario where a lot of users have the same ip (i.e. italian isp fastweb, large corporations, etc). Also, if user has dynamic ip it can change it's own ip address every time he likes...
One of the best ways should be using email address and cookies. User will be able to vote multiple times (you can't avoid this), but at least it will take them some time for each vote.
for a similar project i did 2 verifications ...
i placed a cookie and also saved on the server a hash from users ip + user agent.
this seemed to be pretty effective since even if there are more people that use the same IP the hash with user agent will be different most of the times since it differs for same browser depending on the operating system and other extensions installed.
There is no fool proof way for preventing multi votes. Checking cookie is anothr option.
Regarding Validatin the ip address. What if the user is from a net work which is used by many users?

Categories