10

I'm building a simple web app with an up-vote option. I plan on offering cash rewards for the most up-voted so I want a relatively secure system. I have a couple questions about conception. I know that my post is similar to a few others but none seem to be specific enough to the platform to put my mind at ease.

My web app is utilizing javascript and firebase for loading all of the objects that are being voted on. I'm going to force a user to be logged in and store IP addresses, user IDs etc.

Questions:

  • Is this fundamentally flawed from the start for using javascript? I see a large potential for writing a script that just changes values and re-votes. (maybe I can verify the front end data is correct and that the user exists with an ajax call?)
  • With the off-beat chance my app becomes successful Is this going to be too much front end computing?

Edit: I'm sorry, but I left out the key fact that I do have a larger back end system(WordPress) that handles authentication. The app I'm working on is largely independent from wordpress. I'm simply pulling some user information for filtering purposes. I chose Firebase as a storage solution for its real-time features.

I'm hoping to combat voter fraud with a few methods:

  • low rewards $100/month given away.
  • being logged in isn't a compromise, I actually want users to be registered and verified with human eyes to be eligible to vote. Others can witness the contest but cannot vote.
  • server-side checks. If my app gains popularity I can write scripts to monitor voting patterns for irregularities? if someone is abusing the system, I disable their ability to win.
Front_End_Dev
  • 1,205
  • 1
  • 14
  • 24
  • 10
    The "cash rewards" thing might be a bad idea. You're never, I repeat **never**, going to be able to stop people from going out and buying out a bunch of proxies and VPNs to vote. – mawburn May 31 '13 at 18:07
  • This seems flawed from the start. Security can not be guaranteed on the client side. – andre May 31 '13 at 18:07
  • 5
    As the others said, solely relying on JS to accomplish this is a recipe for disaster. You're going to need to incorporate some server side stuff. – Sethen May 31 '13 at 18:08
  • 2
    Also, you need to think about what happens if the user doesn't have JS enabled at all... Then what? – Sethen May 31 '13 at 18:09
  • Related: [Unique IPs in a voting system](http://stackoverflow.com/q/7775968/710446) and [How to avoid repeated voting from same user?](http://stackoverflow.com/q/10724007/710446) – apsillers May 31 '13 at 18:13
  • 1
    From security.se, [How can an internet contest verify unique votes with only an email as an input parameter?](http://security.stackexchange.com/questions/31526/how-can-an-internet-contest-verify-unique-votes-with-only-an-email-as-an-input-p) – Mike Samuel May 31 '13 at 18:18
  • 1
    You have a couple of questions about *what*? – Jimbo May 31 '13 at 20:08

4 Answers4

8

It is certainly possible to do this securely client-side. However, as noted by others, it does require users to login. If you're already using Firebase, this is actually pretty easy to implement using the FirebaseAuthClient.

You can then couple this with Firebase security rules to enforce that any logged in user can only upvote once. Check out the screencast on the security page for an example!

Your security rules might look like:

{
  "rules": {
    "users:" {
      "$userid": {
        "voted_on": {
          "$articleid": {
            ".write": "!data.exists()"
          }
        }
      }
    }
  }
}

This ensures that you can write any given value to /users/anant/voted_on/article1 exactly once. You can add a .validate rule to ensure that the value is a boolean (or something else).

Anant
  • 7,408
  • 1
  • 30
  • 30
  • I like this, I'm going to look into what it can do tonight! – Front_End_Dev May 31 '13 at 20:13
  • If you want to have an added level of security, such as an IP address check to help slow people down from making duplicate accounts, you could do so with a custom auth token (rather than using the Firebase Simple Login service). https://www.firebase.com/docs/security/custom-login.html – Andrew Lee Jun 01 '13 at 19:07
  • @AndrewLee IP address checks might not be reliable. Multiple members of a household tend to share a single IP address, people at work might also share a single IP address, and broadband providers also tend to periodically change your IP address. – Mike Pugh Jun 02 '13 at 18:48
  • Just a small (perhaps) note: You probably also want to add to the ".write" rule that only the user who is voting can add to the $articleid list. Something like "!data.exists() && auth.uid === $userid" – Jake Apr 17 '14 at 16:04
3

This is what you should probably do:

1) As soon as user votes, you should make an ajax call to the server and update the flag in the database and disable the voting using javascript.

2) If the user refreshes the page and tries to vote up again, the server would be knowing that the vote has already been made(as it is saved in database) so the voting system will appear disabled on the page.

3) If the user tries to enable the voting using chrome tools or firebug by modifying the source of page, you can create a check at database end by setting the composite key on userID and "vote" flag which would prevent the duplicate votes.

Hope it helps..

writeToBhuwan
  • 3,233
  • 11
  • 39
  • 67
2

There is no way to prevent duplicate votes but forcing users to sign up (maybe with email confirmation) and authenticate (thus, storing votes somewhere in your DB and checking). Other techniques are flawed:

  1. cookies/session storage can be disabled or cleared whenever the user wants.
  2. IP address tracking prevents usage behind NATs, proxies and gateways, since all clients will share the same public address (or a small number of).

Still, a user could register multiple accounts and there is no way to prevent this.

A thing you can do is detecting rapid sequences of vote actions, which could be generated by scripts.

Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80
1

Taking advantage of OAuth authentication, it's highly unlikely that users cannott find a way to login via either FB/Twitter/Google/OpenID.

It is still cheap and fast to vote, and in case the user does not want to login via third party services, you can provide an email fallback.

As everybody pointed out already, you have to rely on you own server.

moonwave99
  • 21,957
  • 3
  • 43
  • 64