设置安全的轮询系统

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.

  1. 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 ?

  2. 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

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.

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?

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.

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.