2

Let S be a server and C be a mobile client (iOS/Android App). Assume that the communication between S and C is ciphered with SSL (or any other standard protocol).

The system is a voting application, i.e., S sends some artices to C and C can upvote/downvote them, sending his vote back to S. The thing is that I don't want C to register/signup for this, but also I don't want him to vote more than once.

One could think of something like: when the app is first launched on C, S assigns a UUID to C and C stores it. Then everytime C wants to vote it sends the vote and its UUID and S checks if that UUID has already voted.

But in such case, what prevents someone to create a program that is always asking S for UUIDs and then voting the same article as many times as wanted?

All that comes to my mind is that S and C share a password that is hardcoded and then the system will work this way:

  1. C asks S for a UUID,
  2. S sends C a UUID,
  3. C stores the UUID,
  4. When C wants to vote, sends to S: {vote, crypt(UUID,sharedPwd) }

Of course the moment someone knew that password (and maybe it's easy to get it as it's actually in the client's code...) the system would be jeopardized...

So... How can my server know that the requests are indeed coming from the App? Or may be a different approach: how do some apps with no registration perform authentication?

2 Answers 2

2

I'm afraid what you're asking for is impossible. If you want new users to be able to use your app, someone will find a way to pose as a new user every time and falsifying the votes that way. The only solution is to have a trusted party certifying the identities of everyone, and that won't happen until every ID card out there is a standard smart card with a client certificate in it. As of right now you could in theory rely on a CA, but that would be a huge barrier of entry and nobody will ever use your app.

You could make it more difficult though. Using certificate pinning on the app's side so traffic analysis is more difficult, and obfuscating the binary will slow down potential attackers who want to replicate the behavior of your app, but even then, the attacker just has to uninstall/reinstall your app and it'll appear like a new install on most devices.

If possible on your target devices, you should rely on an identifier provided by the host OS or the app store - that is harder to replicate (or even impossible if your server is contacting the app store's servers to validate the installation of your app) than replicating an app as the OS has ways to access the hardware and get per-device IDs from that (MAC address, IMEI, etc) while your app can't access those directly.

You could also tie the unique device IDs to something harder to obtain, like phone numbers by requiring an SMS confirmation every time the app is installed. It won't stop fraud (and as such is unsuitable for "formal" voting like elections or anything where money is involved) but it will help. It's like DRM, it doesn't need to be bulletproof, it just needs to be stronger than the competitor's apps and attackers will go after the low hanging fruit, leaving your solution alone.

Finally if all you're looking to defend against is mass-voting by bots but don't care about occasional, manual voting then adding a captcha is enough. Of course, this will only work while money isn't involved - otherwise it may still be profitable for the attackers to hire humans to type the captchas and commit fraud that way.

0

You could issue a cookie when S sends the article to C, and C can send the cookie to the server along with UUID. If the cookie is valid (which means session is valid), let the vote happen. If someone tries to send request using someone's uuid, attacker doesn't have cookie in the request, so it would be invalid vote, and you can drop it safely.

Make sure you generate a cookie with proper expiration so that it can increase the validity of the user vote.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .