I want to create a polling website. A client requests to answer the poll using POST, and the server responds with the candidates. The client then sends a POST with the candidate information and the winner to the server, which then stores in the information. I want to prevent a client from manipulating results by repeatedly sending their vote to the server. One way I thought was:

  1. Client requests to vote in the poll.
  2. Server sends a list of candidates, timestamp, and a salted hash created using the candidates and timestamp. The server then stores the hash.
  3. Client picks a candidate, and sends the winner back with the list of candidates, timestamp, and salted hash.
  4. Server computes the hash with the same salt, and checks to see if the hash is a valid hash as stored in the database. If the hash is valid, it honors the vote. If not, then it either silently fails to avoid alerting the attacker or responds with an error.

I want to find a more elegant way to do this though. First, I'm having trouble thinking of a salt which is not static. I don't want the user to be restricted by IP address, so that can't be included in the salt. After that I can't think of a good way of salting my hash.

Second, I want to find a way to not have to store information on the server. If I could create a validation method that can be computed quickly instead of stored that would be better (unless storage is definitively better than computing because it might be faster?).

Third, should I silently fail or explicitly inform the client of an error?


It sounds like you really have two problems here:

  • Preventing replay attacks.

  • Preventing the same client from voting twice.

These are subtly different. A replay attack is simply sending a request multiple times, perhaps with slight variations, and possibly by a third party. Voting multiple times is just that: legitimately voting more than once.

The core problem here is you do not know who the clients are. What if a client moves locations (IP or subnet)? Is it a new client? Even if you think you know who they are, at an abstract level, you do not.

This is not a new problem. By and large, most of the Internet solves this problem by demanding that clients create accounts. Authentication occurs over TLS, ensuring that a client is who they say they are. Once this is done the client can send its vote over the TLS connection where the server stores it in the database. One client ID (e.g. email address or account name), one vote.

This prevents replay attacks: TLS is already hardened against these attacks by design. This also prevents voting multiple times: votes are linked against the account ID in the database, making it trivially easy to see if a particular client has voted already. Simply have a multi-part primary key consisting of the poll ID and account ID. Another field stores the vote. You can add optional metadata such as the IP address and date/time of the vote.

There is no reason to reinvent the wheel here: TLS and some basic database design can easily solve your problem and far better than any home-grown solution can.

  1. Is it feasible to use the table row number where the record is being stored as the salt? (or a function of this unique number).
  2. I would store the information on the server, just because as a matter of principle I would NEVER trust the client in Internetland. If you really want to store information on the client you will be digitally signing it or encrypting it using your private key and verifying it or decrypting it at vote time. Whether this is acceptable depends on the nature of the poll: for election to public office, I would choose the server, where to go for team lunch, I would choose the server for that too.
  3. Give feedback (and log it), otherwise you run the risk of nobody even knowing if legitimate votes being pinched and used before the real voter has time to vote.
  • 1
    How do any of those prevent someone else sending the same message again? – user40980 Sep 9 '15 at 0:34
  • They do not prevent someone else sending the same message again -- but they enable the OP to detect when it happens and this enables them to avoid counting the same vote twice, which is their basic requirement. Also note that theoretically this will not prevent their vote from being stolen and used by a man in the middle listening in to the exchange; One way to achieve that is to use 2 factor authentication but we need to know more about the actual application before making firmer recommendations. OK? – Michael Sep 10 '15 at 23:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.