3

I have a task to create a poll. The idea behind this poll is to be visible on a website, but without users. You dont need to be logged in user to answer the poll. However what I need is to make it so that after voting once you can't vote twice. This is something not really hard and something I have seen often in news sites.

The general solution for this is the cookie. You store information in the cookie and if they submit an answer you store that information in the cookie and you are all good.

However I want to do something even better - I want to make it so if you open Chrome and vote and then open Mozilla you wont be able to vote again.

The first thing that came to mind was using the IP, but then..what if you have multiple computers on one connection? Like in a big office building?

This means that I will need something that is unique to one specific computer no matter his internet connection.

What came to mind is to use something specific and unique to generate ID for the cookie. This means that by using something unique I will generate an ID which always will be the same for a specific computer, no matter the browser and no matter the connection. You can erase the cookie and then when I create new one it will be created with the same ID and I will be able to recognize that someone with that computer already voted for the poll.

My question is - what is unique to computers which I can access via the browser and how? I am using PHP with Symfony and javascript for Front-end.

Again I will summarize what I want to achieve - some way to allow me to recognize a user (computer) without log-in even if that user deleted all cookies and switches browsers or is on different connections. He can use VPN or move from one country to another one and switch internet providers or anything of that sort...as long as he is on the same computer and that computer hasn't received braking changes (fixes, upgrades, etc.) I need to recognize it.

Pavlin Petkov
  • 1,022
  • 3
  • 17
  • 38
  • 1
    Did you take a look at this [question](https://stackoverflow.com/questions/216542/how-do-i-uniquely-identify-computers-visiting-my-web-site)? – Sorix Nov 28 '17 at 16:15

2 Answers2

7

This is called browser fingerprinting.

Check https://browserleaks.com/ for a list of tons of pieces of data you can get about a user. That website uses client-side code you can also use to get all of the data you see there, including things like:

--What fonts they have installed

--What OS they are using

--Their ISP

--What plugins they have installed

--Using <canvas>, a very unique fingerprint in and of itself

--Their screen resolution

and much, much more, especially if the user has Flash, WebGL, or WebRTC enabled. Using this data, you create a "fingerprint" of the user in your database. For example, lets say I visit your site; you record all of the 322 fonts I have installed, what OS I have, who my ISP is, what plugins I have installed, my screen resolution, etc. When I try to go to your site from a different browser and even different IP, you still know exactly who I am from all of that other data you collected.

EDIT: given duskwuff's comment and downvote, I guess I feel compelled to give some links to research and outcomes. Do note that browser fingerprinting is not 100% effective, so should not be used as a unique id as you would in a database to absolutely identify a user, but with the latest techniques you can get very high rates of success. Most websites use it either for ads marketing, or as you intend, an anti-spam technique:

https://panopticlick.eff.org/static/browser-uniqueness.pdf (99.1% effectiveness) http://yinzhicao.org/TrackingFree/crossbrowsertracking_NDSS17.pdf (99.24% effectiveness) http://mickvaites.com/wp-content/uploads/2013/09/T802_Michael_Vaites_2013-BrowserFingerprinting.pdf (95% effectiveness)

EDIT 2: To actually implement this sans high-priced corporate SaaS products: https://www.npmjs.com/package/fingerprintjs2 Under "List of fingerprinting sources" you will see a list of different pieces of data you will get when a user visits your site. You should record this data in your database anytime someone submits a poll. Before allowing the poll submission, query your database for something like "has anyone with this same user agent, language, color depth ... etc submitted the poll in the past? If yes, this is probably someone trying to submit the poll twice, so don't allow the submission." That is a very simplified way to do it, and won't work extremely well; in an ideal world you would want a sophisticated algorithm that would check all the data points and determine the probability the user is the same as before. E.g. maybe they changed their time zone to throw off your spam detection; if all the points are the same except for time zone, that is easy for you to detect.

A simple-ish way to implement this to a decent level of accuracy: use the canvas fingerprint + installed fonts. Canvas fingerprinting is very accurate, and hard to spoof. The same with installed fonts. Those two pieces of data alone will get you a pretty decent spam detection system. Users can disable html canvas in their browser, so you would need to stop them from submitting a poll if canvas fingerprint data is empty. Users can delete and add fonts pretty easily, so fonts alone aren't perfect, but the combination of the two will stop any basic malicious attempts at submitting the poll multiple times.

KayakinKoder
  • 3,243
  • 3
  • 23
  • 37
  • Most of the data points collected by browser fingerprinting are browser-specific. (That's why it's called _browser_ fingerprinting, not _computer_ fingerprinting.) The ones that are shared -- fonts, IP address, screen size, etc -- are not unique enough to use as an identifier. –  Nov 28 '17 at 16:26
  • 1
    Just keep in mind that under this scenario, computers that might have multiple legitimate users (family members, users in a public library, shared devices in schools) would not allow each to have a vote. – Chris Nov 28 '17 at 16:27
  • 1
    @duskwuff not true at all, read up on the latest research on the subject. Browser fingerprinting is very, very effective and used successfully by many of the world's largest websites. 95%+ rates of successful identification are commonplace, with the newest techniques (fonts, canvas, webrtc, OS/hardware) above 99%. – KayakinKoder Nov 28 '17 at 16:28
  • 1
    @KayakinKoder I strongly doubt that. Smartphone/tablet devices make up >50% of web traffic, and most of the factors used in fingerprinting don't work on these devices -- any two devices of the same type running the same OS version will look identical. –  Nov 28 '17 at 16:43
  • 1
    @duskwuff you can doubt it, but read the research first. I am pretty up to date on the latest research and tactics in this field, attend conferences, etc. It's very effective, used by many of the world's largest websites (facebook, craigslist, the list goes on) to detect and prevent spam. – KayakinKoder Nov 28 '17 at 16:48
  • That leads to another question for the OP, though: If Facebook, for example, uses browser fingerprinting - presumably with additional authentication factors - why not use OAuth services offered by such sites as the basis for authenticating your own site visitors? – Chris Nov 28 '17 at 17:16
  • @duskwuff as far as your "mobile devices will look identical" comment, again, not true at all. Not even close to true, in fact. See this answer by the CTO of Augur for an introductory primer on the topic: https://www.quora.com/How-does-the-%E2%80%9CDevice-Fingerprinting%E2%80%9D-in-Mobile-App-Tracking-work-without-UDID-MAC-or-Android-ID-and-how-can-Mobile-App-Tracking-generate-fingerprints-and-achieve-94-accuracy – KayakinKoder Nov 28 '17 at 17:27
  • Okay...but..how do I use it? Do I need to install a plug-in? – Pavlin Petkov Nov 28 '17 at 18:25
  • @ЛуциПетков no, there is no simple way to do all of this (unless you are willing to pay a lot for a corporate SaaS product). https://www.npmjs.com/package/fingerprintjs2 is a JS package that may be good enough for you though. Each of the things you see on browserleaks is either javascript running in the user's browser or server side, http request/response analysis. You will need to store the data in your database, then anytime someone visits your site check your database "has anyone with these same fonts/ISP/geolocation submitted the poll? If yes, don't allow them to submit again". Not simple. – KayakinKoder Nov 28 '17 at 18:36
  • @ЛуциПетков see Edit 2 for some notes on probably the easiest way to implement this. – KayakinKoder Nov 28 '17 at 18:47
1

The only way I can envision doing this is by using a Flash application and using a Shared Object. But this is ugly and can be defeated easily, just like cookies. In short, there is nothing you can manipulate on the client side to do what you propose in a consistent, reliable way.

Chris
  • 254
  • 1
  • 11