Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Avoiding multiple voting

by hakkr (Chaplain)
on Jan 02, 2002 at 19:11 UTC ( [id://135682]=perlquestion: print w/replies, xml ) Need Help??

hakkr has asked for the wisdom of the Perl Monks concerning the following question:

How can I ensure a web surfer can only submit a form once. I am creating an anonymous voting system muchlike the PM nodelet and I need a way to ensure people can only vote once. I am not requiring them to enter any details before voting so the only way I can think of is using cookies. The thing is people can turn off or delete cookies so it would not be very effective.

Is it possible to log the surfers IP address or obtain some sort of unique browser serial number. I know Firewalls mask IP addresses so I'm not even sure requiring unique IP numbers would work. Thanks

Replies are listed 'Best First'.
Re: Single use Only
by Fengor (Pilgrim) on Jan 02, 2002 at 19:21 UTC
    to put it blankly: It cannot be done (at least i can't imagine a way of ensuring everyone can only vote once in an anonymous vote).

    There are several approaches u could try nonetheless:

    • IP-Adresses: You can try to remember every IP-Adress that has already voted. But keep in mind, that firewalls masq IP's so that from outside a LAN with some hundred computers looks like one. Another thing are dial-up user which get assigned a new IP whenever they dial up
    • Cookies: You can set cookies and try to identify those who already have voted. But as you pointed out yourself people can delete cookies
    • Session Management: With SM you can ensure that someone can only vote once per session. But as soon as someone starts a new session he can vote again.
    The fact is that to get accurate votes you need an information which is unique and on which the user has no influence. If it's a vote for registered user only you could use something like a user id. Every registerd user has one and he can't change it.


    -- Terry Pratchett, "Reaper Man"

Re: Single use Only
by Beatnik (Parson) on Jan 02, 2002 at 19:18 UTC
    Classic question once again :)

    Yes, it is possible to grab a users' IP but it's not 100% guaranteed that IP address belongs to a single user (as in proxies, firewalls, etc) or that the IP remains with the same user (as merlyn pointed out numerous times : AOL).

    Possible solutions are Cookies... But again, no way of knowing for sure. Cookies can be rejected, cookie caches can be cleared, cookies CAN be forged, etc.

    What about storing the last submitted form and checking if the newly submitted form is the same??

    ... Quidquid perl dictum sit, altum viditur.
Re: Single use Only
by Amoe (Friar) on Jan 02, 2002 at 19:40 UTC

    Everything said by the other monks is true. But you can come close to blocking one-session multi-submits by generating a random word or number in GD, and displaying it on the submittal page, then checking if the user wrote it right. See merlyn's WebTechniques column for an example of this. ("Keep robots from stuffing your forms", I think)

    However, this relies on people's laziness, which is generally a good bet, but may not be applicable sometimes :) Certainly amongst Perl programmers though...

    my one true love
      No technique is truly secure. Lycos introduced a "one time code" system on their SMS service to prevent automated robots spamming their service by creating a unique number in a GD-created image. Last I heard, someone had created a script that did OCR to read the number out...

Re: Single use Only
by arhuman (Vicar) on Jan 02, 2002 at 19:22 UTC
    I think the monastery use an IP based system,
    but it's not foolproof and you will block all the people behind the same router
    (in the case of lan doing NAT behind a router )
    after the first vote...

    Forget cookies or UserAgent or referers...(too easy to delete/fake IMHO)

    A possible way could be to have a challenge with one part computed by the client (java class?)
    with client hardware's info as part of the computation to ensure uniqueness
    I've never went into this although, I was just wondering...

    UPDATE : To step away from theory, and give more details :
    • Don't forget to store somewhere those who have already voted
    • A challenge to prevent replay attacks
    • using client hardware's info (MAC address,CPU ID in some case,DMPI/BIOS info...) for uniqueness
    • Java class for client side (and WEAK obfuscation)

    "Only Bad Coders Code Badly In Perl" (OBC2BIP)
Re: Single use Only
by davis (Vicar) on Jan 02, 2002 at 19:29 UTC
    Simple answer: You can't, or at least not against the determined.
    HTTP is a stateless protocol, and the webserver, and therefore your CGI are basically unable to tell the difference between one user's browser and another
    I believe the closest you could come is to use cookies, and to force users to accept cookies in order to view the form.
    This is defeatable, because the user can freely edit their own cookie jar, and forcing cookies could also offend some users.
Re: Single use Only
by John M. Dlugosz (Monsignor) on Jan 02, 2002 at 22:12 UTC
    If the user is "logged in", by whatever means, the server knows which user is accessing the page. It can remember that this user has already voted. that is how PM does it.

    You need to use one of the several techniques for keeping a "session", and also authenticate the client and store that information in the session. Then, remember which users have voted, along with all the other personalization settings.


Re: Single use Only - Close Enough
by Rhandom (Curate) on Jan 02, 2002 at 22:14 UTC
    What is the nature of your survey. I can imagine only a few situations that you would ever need to have one person vote once and only once.

    Of all of the methods listed above, the only one that will come close to getting the job done is the one vote per user... of course, a single person could sign up for multiple user accounts and so you have been foiled again.

    You could go the route of trying to uniquely identify the computer via a hardware diagnostic (which is a clever idea by the way ... oops - that's a little to close to what a common new operating system does). However, this doesn't prevent somebody from going to a library with 20 computers or a university with 100 computers and voting once from every computer.

    You could try a combination of the things. But again, this would make it harder to do, but not impossible. Even if you asked for a unique social security number that you verify against a database, a person could use his childrens numbers, friends, etc.

    So the question is, what is the nature of your survey. For most of the time, doing an IP check is "close enough." Yes you may block out a number of people under the same firewall. If it is a broad internet survey, then this really shouldn't matter (show a polite message saying that the class C they are on has already submitted an answer -- yes, use the class C as most dial ups still should put a person on the same class C).

    If you really need a single vote per person and critical data depends upon it, ask for a registration fee, social security number and make them sign a contract (via fax) that is prosecutable by law. Or maybe you should do your survey a different way (such as live and in person). If it really isn't that sensitive, be happy with the class C IP.

    As we always used to say... "Close enough for atom bombs and hand granades."

    my @a=qw(random brilliant braindead); print $a[rand(@a)];

      It's for a competition where surfers vote for the winner and the prize may have monetary value thus an incentive to cheat. Hardware diagnostics sounds neat but I've got no idea how to do it. Seems in this case there is only no ways to do it. As suggested I'm going to try to use a combination of cookies, sessions and IP but for now failing that we may have to do it for fun instead of prizes. Unfortunately I can't add a step for random number validation or registration but I'll keep them in mind for the future. I'm sure the online raffle they want next will cause me even more problems :(
      thanks anyways
Limiting form reuse without registration {Re: Single use Only}
by dave_aiello (Pilgrim) on Jan 02, 2002 at 22:17 UTC
    There's a famous saying attributed to Yogi Berra, a member of the Baseball Hall of Fame: "Nobody goes there anymore. It's too crowded."

    The only practical way I've found to restrict the reuse of web-based forms without requiring user registration is to log the apparent IP address. If your site is not very popular, this works perfectly well. On low-volume sites, difficulties generally only occur if everyone who visits your web site does so from home and comes to you via the same large, consumer-oriented ISP.

    The problem becomes more complicated when your site actually becomes popular. I recommend reading the comment on a typical Slashdot poll results page: "This whole thing is wildly inaccurate. Rounding errors, ballot stuffers, dynamic IPs, firewalls. If you're using these numbers to do anything important, you're insane." This is the most practical advice I've ever seen on Slashdot, and instructive to all of us who aspire to create a popular web site.

    Dave Aiello
    Chatham Township Data Corporation

Re: Single use Only
by Mojo Geek (Initiate) on Jan 03, 2002 at 02:03 UTC
    A lot of good comments, but they all boil down to the same thing: "You can't get there from here." Re-examine the need for "one time only". These people here can write perl to stuff the PM ballot box. They don't in general because: 1) It would prove nothing. 2) They are interested in the untarnished results. Myself I vote for cookies. If I really go to the trouble to delete the cookie (after finding it) and go back to your site and vote again... how much damage have I done? How much have I skewed the results? Suppose I take 15 minutes and vote three times. Big woo? The only sure proof way (and there is no sure proof way) is to require registration, which you opted out when you said "anonymous".

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://135682]
Approved by root
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-06-24 13:58 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.