FYI: changes to navigator.plugins[] enumeration to reduce fingerprinting
Chris Peterson <[email protected]> Fri, 22 Nov 2013 22:09:05 -0800
| Newsgroups | gmane.comp.mozilla.devel.plugins |
|---|---|
| Message-ID | <[email protected]> |
Last night, I landed a fix for bug 757726 that will "cloak" uncommon plugin names from navigator.plugins[] enumeration, as described in the HTML Standard's section on "hidden plugins" [1]. This change does *not* disable any plugins; this change only affects the visibility of the plugin *names*. If you find that a website no longer recognize your installed plugin when running Nightly 28, this is likely a side effect of bug 757726. Please file a new bug blocking bug 757726 so we can fix our whitelist of uncloaked plugin names or have a web compatibility evangelist reach out to the website author to fix their code. Web analytics software often tracks people using a "fingerprint" of their browsers' unique characteristics. The list of installed plugins and system fonts are the largest sources of unique entropy identifying a person's browser. For more information about fingerprinting, see the Mozilla wiki [2] or EFF's Panopticlick [3]. This code change will reduce browser uniqueness by "cloaking" uncommon plugin names from navigator.plugins[] enumeration. If a website does not use the "Adobe Acrobat NPAPI Plug-in, Version 11.0.02" plugin, why does it need to know that the "Adobe Acrobat NPAPI Plug-in, Version 11.0.02" plugin is installed? If a website does need to know whether the plugin is installed or meets minimum version requirements, it can still check `navigator.plugins["Adobe Acrobat NPAPI Plug-in, Version 11.0.02"]` or `navigator.mimeTypes["application/vnd.fdf"].enabledPlugin` (to workaround problem plugins that short-sightedly include version numbers in their names). For example, the following JavaScript will reveal my installed plugins: for (plugin of navigator.plugins) console.log(plugin.name); "Shockwave Flash" "QuickTime Plug-in 7.7.3" "Default Browser Helper" "Unity Player" "Google Earth Plug-in" "Silverlight Plug-In" "Java Applet Plug-in" "Adobe Acrobat NPAPI Plug-in, Version 11.0.02" "WacomTabletPlugin" navigator.plugins["Unity Player"].name // querying a cloaked plugin "Unity Player" But tomorrow that same JavaScript will not reveal as much personally-identifying information about my browser: for (plugin of navigator.plugins) console.log(plugin.name); "Shockwave Flash" "QuickTime Plug-in 7.7.3" "Java Applet Plug-in" navigator.plugins["Unity Player"].name // querying a cloaked plugin "Unity Player" In theory, all plugin names could be cloaked because web content can query navigator.plugins[] by plugin name. Unfortunately, we could not cloak all plugin names because many popular websites check for Flash by inefficiently enumerating navigator.plugins[] and comparing plugin name strings. The policy of which plugin names are uncloaked can be changed in the about:config pref "plugins.enumerable_names". The pref's value is a comma-separated list of plugin name prefixes (so the "QuickTime" prefix will match both "QuickTime Plug-in 7.7" and "QuickTime Plug-in 7.7.3"). The default pref cloaks all plugin names except Flash, Shockwave (Director), Java, and QuickTime. To cloak *all* plugin names, set the pref to the empty string "". To cloak *no* plugin names, set the pref to magic value "*". Known issue: Mozilla's Plugin Check website will no longer see cloaked plugin names when it enumerates navigator.plugins[], so the website will only version check the Java, QuickTime, Flash, or Shockwave plugins! See bug 938885 for a description of a Plugin Check fix to support all plugins. Personally, I believe Plugin Check should be an automatic feature integrated into Firefox, not a website that 99% of users will never visit. I started hacking on this patch in my spare time 13 months ago. I finally found some weekend time to complete it. :) cpeterson [1] http://www.whatwg.org/specs/web-apps/current-work/#hidden-plugin [2] https://wiki.mozilla.org/Fingerprinting [3] https://panopticlick.eff.org/index.php?action=log&js=yes