
Firefox takes a bite out of the canvas ‘super cookie’ - robin_reala
https://nakedsecurity.sophos.com/2017/10/30/firefox-takes-a-bite-out-of-the-canvas-super-cookie/
======
sempron64
One of the major vectors for fingerprinting in various ways is font rendering.
It's extremely surprising how integrated with the OS font rendering is,
considering it's something that can be done completely seamlessly in userspace
for most applications.

I spent a long time integrating libpango/cairo
([http://www.pango.org/](http://www.pango.org/) and
[https://www.cairographics.org/](https://www.cairographics.org/)) into a semi-
toy opengl game engine I wrote which had a Windows target, and was baffled at
the level of complexity/interdependency required to build it. Gecko (firefox's
rendering engine) maintains a fork of cairo
[https://github.com/mozilla/gecko/blob/0ea4c5812c2adecbed1d84...](https://github.com/mozilla/gecko/blob/0ea4c5812c2adecbed1d84884e9695628a47502c/gfx/cairo/README)
, which is as far as I can tell the only way to statically link it. Both these
libraries require Glib.

There isn't an alternate minimalist open-source font rendering library as far
as I'm aware, simply because the task of handling all font-rendering edge
cases in all languages is so gargantuan. So we're stuck with a huge
intertwined set of poorly understood C libraries, tightly integrated into the
system and every application and ever-exploitable.

~~~
rossy
The real problem is that people get used to how their operating system renders
fonts, and different operating systems render fonts very differently. The
difference between how macOS and Windows render fonts is almost philosophical.
macOS does not hint fonts at all in an attempt to preserve a font's character
at small sizes, but Windows applies aggressive hinting (and no anti-aliasing)
in the Y-direction to make fonts sharper and more readable, even if it totally
changes the shape of the letters.

On Windows, at least, fonts can also differ between monitors (even on the same
computer.) The built-in ClearType tuner tool lets the user adjust the font
rendering gamma for each monitor individually. It would be a shame if this
didn't have an effect in the browser, where users probably do most of their
reading these days.

If you made your own simple from-scratch font rendering library that
rasterized glyphs to the same array of pixels on every operating system,
regardless of user settings, I guarantee your users would be upset. When you
render a lowercase 'e' to a 6x6 pixel grid, any slight difference in rendering
makes a huge difference to the character of the letter, and it's the sort of
thing that contributes to the "uncanny-valley" feeling that non-native apps
have. This is why Pango and Firefox go through so much effort to use the
native renderers on each platform and why they may seem complicated to an
outsider.

~~~
jonnycomputer
I think most people don't really care that much how their fonts are rendered,
or would even notice a change. (And no, I don't have data to back that up)

edit:

The emphasis here is on "most". In a world where an OS will have many millions
of users, at least more than a few are going to care a lot about things like
the differences between font renderers; programmers and graphic designers are
no doubt among them. But the typical user? Without real data to back it up,
count me as skeptical.

~~~
rossy
For an example of how much people care, look up all the outrage that happened
when Chrome switched between two very similar Windows font renderers (GDI and
DirectWrite.) Example: [https://www.change.org/p/google-inc-bring-sharp-fonts-
back-i...](https://www.change.org/p/google-inc-bring-sharp-fonts-back-in-
google-chrome-disable-directwrite)

If anecdotal evidence counts, I've heard lots complaints about font rendering,
even from people in real life and non-technical people. (I like the fonts on
X. Why does Y look so bad? Why can't it just look like it does in Word on
Windows?)

It turns out that if people spend most of their lives/jobs looking at text
that appears a certain way, they will get accustomed to it. If these people
are using LoDPI monitors where they can perceive each individual pixel, you'd
better hope your custom font renderer replicates your users' favourite
renderer down to the exact pixel layout of each glyph.

~~~
pcwalton
I don't think you need to be accurate to the pixel level, unless you're
targeting bilevel (black and white) rendering. (This is empirical: nobody who
I've tested my custom font renderer with has been able to tell the difference
between it and the OS renderer, once the same features are enabled.) But you
_do_ need to do everything that the OS does: gamma correction, TrueType
hinting, subpixel AA, autohinting, stem darkening…

~~~
rossy
Yeah, that's fair. I think there's a "Windows XP" preset for Infinality-
patched FreeType and it gets pretty close to what Windows does. Its rendering
of 9pt Segoe UI is near identical to Windows', except for slightly softer font
smoothing, but this doesn't seem to be annoying for Windows users (it's
probably less than the difference between GDI and DirectWrite.)

I heard of this because a friend switched from Windows to GNOME 3 a little
while ago and told me about the Infinality preset. He seemed to be very happy
with it.

------
mschuster91
I don't get why Battery Status API was dropped entirely instead being
"castrated"... by default, allow clients to only detect <5%, <25%, <50%, <75%,
<=100% (or simply <25% & >25%) so that e.g. Unity or other high performance
apps can say "do you really want to play Unreal Tournament with low battery".

This could also be used by ads or stuff like background monero miners to
prevent killing the user's battery...

~~~
raverbashing
You're counting at people accessing your battery level and using it for good
intentions when that's the minority of web pages

Most will use it to try to push you harder "before your battery runs out"

~~~
harsh1618
> Most will use it to try to push you harder "before your battery runs out"

An example of this would be an app like Uber charging you more if your battery
level is low. They already know that people with low battery are willing to
pay more: [https://www.forbes.com/sites/amitchowdhry/2016/05/25/uber-
lo...](https://www.forbes.com/sites/amitchowdhry/2016/05/25/uber-low-battery/)

~~~
matt_kantor
This reasoning could be extended (and maybe it should be) to remove
APIs/headers allowing detection of OS/browser version (maybe Mac users are
willing to pay more?), screen size (bigger monitor = more disposable income?),
etc. For all of them there are tradeoffs, but it would be an interesting
exercise to think about.

------
Jonnax
There are a ton of different methods for fingerprinting a user.

Your unscrupulous ad broker or other actor intending on tracking you will be
using a combination of these.

Each extra one adds another circle to the Venn diagram narrowing you down.

I'm pretty sure that almost everyone (private browsing or not) is identifiable
through their browsing to at most 2-5 different users.

The EFF has a site that tests your browser for some fingerprints and tells you
how unique you are:
[https://panopticlick.eff.org/](https://panopticlick.eff.org/)

Another thing I noticed was that Chrome on Android, sends your phone model and
software build number as part of the user agent.

If you don't have a popular phone, on a carrier customised rom, and with the
other advertising info. You're likely unique.

~~~
Balgair
Oh hey, their site actually looks nice now and is useful.

Also, try this one for Chrome, it should help with the fingerprinting issues:
[https://chrome.google.com/webstore/detail/random-user-
agent/...](https://chrome.google.com/webstore/detail/random-user-
agent/einpaelgookohagofgnnkcfjbkkgepnp?utm_source=chrome-app-launcher-info-
dialog)

~~~
lawl
Randomizing your useragent is the worst idea ever.

Your fingerprint won't conform to the features that are expected. I won't go
into too much detail here, on purpose. But e.g. if you claim to be Firefox
while using chrome, that's completely detectable, server side, even without
javascript.

If you have javascript it's of course even easier to just check if your
browser supports the features it should according to its user agent.

Edit: Btw. I have actually reversed some fingerprinting JS code in the wild,
and yes, they do check if you lie about your useragent.

~~~
Feniks
Funny, I thought we had web standards? Guess nobody gives a shit anymore. Your
site shouldn't even have to ask for the useragent.

~~~
lawl
HTML5 is a living standard, so naturally different browser versions will have
different features implemented.

Also, there's the thing where you can conform to a spec but it's still
possible to tell a difference in implementation by observing certain things.

For example the non cryptographically secure random number generators in
chrome and firefox used to be different algorithms. So if you seed the RNG
with a number and call it, you used to get different results for firefox and
chrome and you could tell if their user agent is lieing. (actually it was a
bit more complicated than that, you can't seed Math.random in JS, but you get
the point)

This isn't about sites needing that info to work correctly. This is what sites
do for fingerprinting.

------
giancarlostoro
I wonder when Safari will follow this example given the efforts they're taking
to make their browser more privacy focused where it sorta counts, in stopping
the different ways advertisers use to spy on you. Now that Flash is on it's
way out the door, it's up to the DOM to be abused by advertisers. I think a
safe bet is to disallow canvas manipulation from "Third-Parties" as a good
first step, maybe by default?

------
nwah1
Canvas API allows fingerprinting precise enough to, by itself, create a unique
identifier for a user.

However, fingerprinting doesn't require any kind of single magic API, but
almost certainly will use a collection of techniques to narrow down users. If
they know your browser version, default language, screen resolution, etc those
three alone can narrow you down by many orders of magnitude.

And they are adding more APIs like Device Memory which, while not as precise
as a canvas fingerprint by itself, could probably whittle it down an order of
magnitude further.

Apparently turning on "Do Not Track" has long been known as a way to single
you out on the web. You'll help them narrow you down by about three orders of
magnitude. It was a silly idea to begin with.

~~~
gkya
> Apparently turning on "Do Not Track" has long been known as a way to single
> you out on the web. You'll help them narrow you down by about three orders
> of magnitude. It was a silly idea to begin with.

Wouldn't that be solved if FF turned DNT on by default?

~~~
mook
It would also make it even more useless. IE originally had it default on; they
turned it off after people complained that it meant advertisers wouldn't
honour it anymore.

[https://en.wikipedia.org/wiki/Do_Not_Track#Internet_Explorer...](https://en.wikipedia.org/wiki/Do_Not_Track#Internet_Explorer_10_default_setting_controversy)

~~~
gkya
Well it was useless to begin with anyways, as it's just kindly asking ad-
publishers to please not track you, which is the closest thing we have to the
platonic idea of naivety.

~~~
yborg
It's not useless in the context of a legislative requirement to honor it,
which was the original goal that DNT was supposed to drive to. Since we now
have pretty much 100% regulatory capture in the Internet space that of course
is now dead.

~~~
chimeracoder
> It's not useless in the context of a legislative requirement to honor it,
> which was the original goal that DNT was supposed to drive to. Since we now
> have pretty much 100% regulatory capture in the Internet space that of
> course is now dead.

It was never really likely to happen, especially when even advocacy groups
like the EFF opposed legislative approaches to enforcing DNT.

------
helenius
Looks like this needs privacy.resistFingerprinting set in about:config.

>I think it's a bad idea to advertise this to the general public, because you
have to enable the "privacy.resistFingerprinting" pref for this to work.

------
na85
The sad part is that this requires a sort of herd immunity to be effective: if
85% of users are still running chrome from within the Facebook app, the added
anonymity provided by this technology is (if I understand correctly) less
effective at preventing tracking.

~~~
Ajedi32
Even worse; by default this setting is disabled even for Firefox users. If 95%
of users don't enable `privacy.resistFingerprinting`, then that setting is far
less effective for the 5% of users who do.

------
mike-cardwell
I've been using the following addon to block this fingerprinting for a while
now: [https://addons.mozilla.org/en-
US/firefox/addon/canvasblocker...](https://addons.mozilla.org/en-
US/firefox/addon/canvasblocker/)

~~~
SN76477
No canvas is a full blown canvas blocking addon. addons.mozilla.org/en-
US/firefox/addon/no-canvas-fingerprinting/

It is developed by multiloginapp.com a privacy first browser suite.

~~~
bpicolo
Looks like the chrome equivalent is:
[https://chrome.google.com/webstore/detail/canvas-
defender/ob...](https://chrome.google.com/webstore/detail/canvas-
defender/obdbgnebcljmgkoljcdddaopadkifnpm?hl=en)

~~~
lukaa
If you use Chrome than you don't care about privacy at all so suggesting
privacy extensions for chrome is ludicrous.

~~~
icebraining
I don't use Chrome, but this hyperbole. You may not mind that Google gets your
info but still dislike that every ad network out there does.

~~~
wolco
Google runs many ad networks

------
gkya
> Fingerprints use information that’s gathered passively from your browser
> such as the version number, operating system, screen resolution, language,
> list of browser plugins and the list of fonts you have installed.

Why any of this information, apart from the screen resolution and the language
(assuming it's the Accept-Language header's contents), is accessible to the
web pages anyways?

~~~
incompatible
Agreed, it seems to me Firefox doesn't need to tell every site that I'm using
"X11; Ubuntu; Linux x86_64; rv:56.0" right in the request header. That's
surely a bit help with fingerprinting.

Perhaps the sites could figure it out anyway with more effort, but at least
force them to make the effort.

~~~
hsivonen
We tried to get rid of the Ubuntu bit years ago but failed. Ubuntu has an
incentive to broadcast that users are using the Ubuntu-shipped Firefox.

Basically everyone who ships a browser wants to shout: “Look at me! I have
market share!”

Many sites vary native-code downloads by platform, so removing OS/CPU would
cause unhappiness there.

------
SubiculumCode
Its unfortunate that using Firefox is a decent identifying feature by itself
these days. Hoping for a change in that trend.

~~~
jonnycomputer
Yeah I just noticed that on Panopticlick; a full 12 bits of information!

~~~
MichaelGG
Is that for FF or your specific user agent? I always thought Panopticlick
wasn't being fair there. Browsers update all the time, so your agent is
changing every 6 weeks. If they are comparing your UA of today against UAs
from their entire project, it won't be remotely accurate.

~~~
jonnycomputer
for User Agent actually. And, my test with Chrome gave me a similar score.

Yes, agents change relatively rapidly, so unless trackers have a model
predicting User Agent change, a tracking profile is only good for only so
long.

Still, I suppose that one could either try to find the most common User Agent
string, and set your browser to that, or have it change somewhat
stochastically (but only enough so we don't compromise legitimate uses)

------
vanderZwan
This "breaks" some libraries with a legitimate use of reading the canvas data,
like favico.js[0] (although arguably, the only reason favico.js has to read
the canvas data is because the favicon API is stuck in the nineties)

[0] [https://github.com/ejci/favico.js](https://github.com/ejci/favico.js)

~~~
maccard
I have to say, if losing this “feature” is the worst that happens, I’m totally
ok with that.

~~~
phkahler
That's how I feel about most browser "features" these days. What ever happened
to plain old static sites? Why does everything need little floating and
collapsing stuff all over? And fade-in imagery and all that nonsense.

~~~
BenjiWiebe
And even collapsing, fading, and floating can be done with CSS alone. No
JavaScript needed.

------
donatj
This seems like a hack of a solution that breaks more than it solves.

I think the "correct" solution would be for canvas text rendering to be better
specified in the standard such that it couldn't be used for fingerprinting.

We'd all benefit from standardized canvas text rendering in the long run.

------
superkuh
Another solution is to leave javascript off by default and only whitelist.

------
ChrisSD
Will extensions be able to ask for the permission at install and then be able
to use it in the background without having to explicitly ask each time?

I ask because it's useful to be able to draw an image to canvas to then
extract image data without having to parse the file format in javascript.
Having to pop up a permission dialog each time would simply annoy the user.

~~~
robin_reala
Test it? It’s simple enough to download Nightly, set the flag and load in your
extension.

------
rc_bhg
At this point, I really hate anyone who is still using Chrome. You need to
support Firefox and make it a force to recon with.

~~~
smcl
I'm using Chrome on my personal laptop running Debian 9 since Firefox is still
a minor pain on Debian. The "firefox-esr" package is based on version 52 and
it's become usable again (IMO) since 56.0 or so - where I switched on my
Windows based work laptop. The alternatives to using firefox-esr are OK but a
bit fiddly - extract a tar.gz somewhere and add to PATH or muck around with
symlinks, or install via apt using an unsupported third party (Ubuntu) package
source.

That's my excuse, not great but switching is on my TODO :-)

~~~
Sylos
Personally, I keep the ESR-package installed, which means the .desktop-file
and icon and such continue to be in their correct places, and then I just
override the firefox-command via the PATH. So, in steps:

1\. Download the tar.bz2 off of Mozilla's webpage.

2\. Unpack it into a directory where you want to keep it. Make sure your user
has write permissions to that directory, otherwise the auto-updater won't
work.

3) In your PATH, place a file with name "firefox" and content: #!/bin/bash
/path/to/where/you/unpacked/firefox/firefox "$@"

4) Make that file that you just put into your PATH executable (chmod +x
/path/on/your/PATH/firefox).

(I'm actually not on Debian, for me it's rather that I replace Firefox Stable
with Firefox Nightly, but I don't think this makes a difference.)

------
ballenf
What are the legitimate uses for a webpage to "read" the content of a canvas
element?

~~~
humblebee
A trivial use case would be to save a drawing the user has created as a
jpg/png and allow the user to download it.

------
tigerBL00D
It sounds like the major sources of variations in canvas behavior are the OS
and the browser. So why would results of using this canvas method not
correlate strongly with just using user agent string?

~~~
jerheinze
That's not true:

> Subtle differences in the video card, font packs, and even font and graphics
> library versions allow the adversary to produce a stable, simple, high-
> entropy fingerprint of a computer. In fact, the hash of the rendered image
> can be used almost identically to a tracking cookie by the web server.[1]

[1] :
[https://www.torproject.org/projects/torbrowser/design/](https://www.torproject.org/projects/torbrowser/design/)

------
SubiculumCode
Surely not all browser version numbers are required for a site to optmize
rendering. Surely some versions could be collapsed? Too much info is just
given away.

I applaud Firefox and Mozilla. More can be done though.

~~~
gruez
>Surely not all browser version numbers are required for a site to optmize
rendering. Surely some versions could be collapsed?

firefox only shows the major revision (ie. the one that changes every 6 weeks)
[https://developer.mozilla.org/en-
US/docs/Web/HTTP/Headers/Us...](https://developer.mozilla.org/en-
US/docs/Web/HTTP/Headers/User-Agent/Firefox)

------
billrobertson42
Could you defeat canvas fingerprinting by adding a bit of subtle random noise
to the canvas every time it is rendered to an image before sending off to the
server for fingerprinting?

~~~
MichaelGG
Generally noise never works to defeat timing or fingerprinting attacks. It
just makes it slightly harder.

