Pointers for building a plugin for browser fingerprinting


(Cameron Carmichael Alonso) #1

Based on the discussion from my thread:

I decided to try my hand at building a plugin that would help prevent suspended users from returning by blocking their browser fingerprint (see panopticlick.eff.org). My plan for this plugin involves:

  • calculating a browser’s fingerprint on plugin initialise (using the FingerprintJS2 JavaScript library)

  • save it to the database based on the user’s id if it doesn’t already exist (there should be a single object per each fingerprint tied to the user - we capture every unique fingerprint a user logs in with to prevent access to all device in the future)

  • on load, query by the calculated fingerprint to see if it is blocked; perform a similar action to an IP block if this is the case, or allow the user to access the site if they’re not blocked.

I’ve made a bit of progress below:

Now the tough part for me is the fact I’m completely new to Ember and Rails, so this is taking a bit of getting used to. I’ve based this on other plugins (such as the discourse-staff-notes plugin) to help get a good structure and to learn how this stuff all works.

In plugin.rb, I believe I’ve set up a model interaction layer. The model is called by the saveFingerprint function in /assets/javascripts/controllers/fingerprint.js.es6, and I’m trying to call this function (exported as an action) from the initializer fingerprint.js.es6 file.

From what I’ve gathered, this is theoretically how I’d call the saveFingerprint function from the initializer:

However, this is undefined (expected) and I’m not sure how this is declared.

I’d welcome any input/contributions from someone a bit more experienced as to how I should go about this and how


Build a browser fingerprinting plugin
(Robin Ward) #2

By default in Javascript, when you create a function() closure, you create a new context with a new this.

Since your sample code above includes two function()s, the value of this will be overridden both times.

An easy way to get around this is to replace your function() with the ES2015 Arrow.

Having said that, even if you do fix it, the value of this in the initializer does not have a this.get('controllers') in it. You’ll need to look it up on the container, like:

container.lookup('controller:fingerprint') instead.

(the container is passed as an argument to the initializer).


(Kane York) #3

Another tip: you should store the data in the PluginStore.


(Cameron Carmichael Alonso) #4

I think that was what I was aiming to do (basing it on the Staff Notes plugin as it appeared to do the same)


(Jeff Atwood) #5

Did you make any progress on this? We’re sponsoring it, if so.