Hey Guys ... I was thinking today about ballot stuffing. As
is right now, phpesp does nothing to prevent this (except
in private surveys). I want a way to at least provide some
level of protection against stuffing attempts. At the least
you should not be able to hit reload on the "Thanks" page
and have it be counted again. Here is what I was thinking:
(and this might have the bonus of being able to go back and
forth on a multipage survey)
. When someone loads the first section (or only section in
a survey w/o pages) a random key is generated. Call this
key K, which should be 32-bits.
. Store this key in a column of the 'response' table, along
with the next response id (autoincrement).
. Put the key C, and response id RID on the survey page in
hidden form fields.
. On a submission, we check the following things, only if
all tests pass do we store the response:
1) Lookup the key K for the RID submitted. Check against
submitted key.
2) The current time is less than 24 hours different than
the time the RID was stored in the response table.
3) The response RID is not already marked completed.
4) IP/userid is same as when RID was created. (?)
Pluses:
. Hitting reload won't do anything.
. You can't just make up RIDs and submit.
Minuses:
. You could still have a script stuff the ballot, but it
would have to parse the page so it'd be marginally harder
to write and slower.
. More data (4 bytes per response) to store in database ==
more disk usage
Big Minus:
Far more RIDs could be wasted since one is generated at
the *first* page, rather than the second. With a unsigned
int there are 4 million RIDs ... this would only be a
problem on high volume sites.
====
There is no way to prevent stuffing, a script that parses
the page will always work, unless you block by IP address,
which is a bad thing to do, and I won't do it. This method
above will force anyone trying to ballot stuff to write a
script that reads the page first ... we track submit times
and possibly IP addresses, so it should be easy to see a
pattern from a script.
Thoughts/Comments? Want to code it?
-James
|