4

I am working on a PHP script that allows users to vote on certain items. Any user whether logged in or not can vote. Consider the following cases:

  1. If the user is logged in, I can log user's id, and can restrict voting on the same item if he tries to vote again.
  2. If the user is not logged in, I can log user's IP, and restrict voting on the same item, from the same IP.

If it's the first case, there's no need to log the IP. Now, the second case is driving me nuts, sort of. I was wondering that it may happen that the user may be changing IP, and then votes again on the same item. Now, even if I use Cookies or Session vars, it may also happen that the user is starting a new session (or has deleted the cookies) to vote on the same item again.

Am I missing something? If not, how to handle such situations? Any thoughts?

abhisek
  • 924
  • 1
  • 13
  • 27
  • If the user is logged in, why not just lock the vote to their account? (The IP lock is redundant in this instance.) Also, if you care about the accuracy of the voting, only allow logged in users to vote. :-) – John Parker Jan 24 '11 at 22:32
  • since the corporate proxy has a few thousand ip's i could vote quite a few times by hitting refresh also you would stop others voting thinking they are me because of the proxy also; ergo, using ip is useless. –  Jan 24 '11 at 22:38
  • @middaparka, I am planning to make it open-source. So it's the developer's choice what he wants to do/his needs are. I myself would prefer logged in votes. But if it's a blog or similar site, not all users are logged in. Beats me how they deal with such situation. – abhisek Jan 26 '11 at 03:43

3 Answers3

6

I would seriously consider use a Captcha, reCaptcha is a good choice.

You could restrict by IP address, but its possible for a number of people to share 1 ip address, such as a small school or business. Its also trivial to bypass because proxies are free and plentiful. Its also error prone because sometimes a load balancer will change the IP address during a session. If you really want to limit the number of vote per person your best bet is to require them to login to a user account and store the votes in your database.

rook
  • 66,304
  • 38
  • 162
  • 239
  • +1 I should have thought of this when answering, but didn't. Good one! :) – Wilhelm Murdoch Jan 24 '11 at 22:43
  • @Rook, I see your point but it's more like a upvote/downvote system. Having to enter captcha text for such an activity can be discouraging for the users. – abhisek Jan 26 '11 at 03:38
  • @abhisek if you want to make an omelet you have to break some eggs. If you want to stop automation, you have to use a captcha, or require a user account. – rook Jan 26 '11 at 19:31
  • @Rook, you're possibly right. But I guess we can do it in another way. The non-loggedin client has to enter captcha only for the first vote on the page. All other votes on the _same_ page won't have to enter captcha. How about that? – abhisek Feb 05 '11 at 03:01
  • 1
    @abhisek then a user could bypass one, and then use a bot for the other votes. A good compromise would be the first vote and then every 5 votes after that. – rook Feb 05 '11 at 03:24
2

First off, there are a few ways to grab a client's IP address using PHP. Here are 3 methods that I know of:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else if (isset($_SERVER['HTTP_CLIENT_IP'])) {
    $ipAddress = $_SERVER['HTTP_CLIENT_IP'];
} else if (isset($_SERVER['REMOTE_ADDR'])) {
    $ipAddress = $_SERVER['REMOTE_ADDR'];
}

Second, if you're worried about volatile storage, such as cookies or sessions, it may be best to have a database table which stores these values. It could be a simple table with 3 columns: client_ip, item_id and date_created. This would allow you to track whether a specific ip address was used to vote for a certain item.

Now, the only problem I see with this is if the client is at work and sitting behind a proxy. So, I guess you have a few options, each with their own pros and cons.

Wilhelm Murdoch
  • 1,806
  • 1
  • 22
  • 42
  • 1
    `HTTP_X_FORWARDED_FOR` and `HTTP_CLIENT_IP` are pulled from the http header and there for can be spoofed with curl or tampterdata. `REMOTE_ADDR` is pulled from Apache's TCP socket, which cannot be spoofed over the open internet. – rook Jan 24 '11 at 22:53
  • I am relying on REMOTE_ADDR :-) @Rook, thanks, didn't know that. – abhisek Jan 26 '11 at 03:40
1

You can try using evercookie, it's kinda difficult to clear

German Rumm
  • 5,782
  • 1
  • 25
  • 30
  • 1
    Evercookie is a zombie cookie that is stored several places on users browser, and for a normal user it is hard to know all these places and how to totally get rid of it. The use of it is controversial, since it kind of undermine the users privacy. http://en.wikipedia.org/wiki/Zombie_cookie –  Nov 25 '11 at 09:34