Post Reply 
Protecting identity - blocking System Fonts info
Dec. 02, 2010, 10:36 PM
Post: #1
Protecting identity - blocking System Fonts info
Ad companies try to use browser fingerprints to track users. They think that now it's move reliable then cookies. Some discussion about it you may find here: <a href="http://www.dslreports.com/forum/r25143854-Fingerprinting-PCs-Phones-For-Marketeers">Fingerprinting PCs & Phones For Marketeers - DSLReports Forums</a>.

Here is web site that offers the test: <a href="http://panopticlick.eff.org/">Panopticlick/</a>

In this thread I'm looking into a way to block from getting "System Fonts" info. They (the test site) achieves that by using the code:
Code:
function get_fonts() {
  // Try flash first
    var fonts = "";
    var obj = document.getElementById("flashfontshelper");
    if (obj && typeof(obj.GetVariable) != "undefined") {
        fonts = obj.GetVariable("/:user_fonts");
    fonts = fonts.replace(/,/g,", ");
    fonts += " (via Flash)";
    } else {
    // Try java fonts
    try {
      var javafontshelper = document.getElementById("javafontshelper");
      var jfonts = javafontshelper.getFontList();
      for (var n = 0; n < jfonts.length; n++) {
        fonts = fonts + jfonts[n] + ", ";
      }
    fonts += " (via Java)";
    } catch (ex) {}
  }
  if ("" == fonts)
    fonts = "No Flash or Java fonts detected";
  return fonts;
}

I guess to block that info it's enough to remove "/:user_fonts" (replace it with empty string "") from Flash and remove "getFontList" function call from Java.

IMHO, there is no need for getting that info by any web site at any time. So, the filter could just block that for all of the sites.

Question: how to make a simpe filter that does it?

Thank you in advance!
Add Thank You Quote this message in a reply
Dec. 03, 2010, 07:05 AM (This post was last modified: Dec. 03, 2010 07:06 AM by JJoe.)
Post: #2
RE: Protecting identity - blocking System Fonts info
First, not a js expert or flash or java.

The info exists after the nosey flash or java applet runs. The javascript variable allows that info to be used outside flash or java. Nosey sites probably won't show or want you to know about the info.

I don't think we can expect to filter compressed flash or java files.

The Proxomitron can filter this javascript. However, I think these names are arbitrary and could be hidden. This looks like Whac-a-mole to me.

Disabling flash and java is probably the only way to be sure this info is not shared. But then, the nosey sites will know that flash and java are disabled. Wink

Code:
[Patterns]
Name = "To start, test at panopticlick.eff.org/index.php?action=log&js=yes"
Active = TRUE
Bounds = "function\s\w \{$INEST(\{,\})\}"
Limit = 1024
Match = "(\0\{)+{1}*"
        "(flashfontshelper|user_fonts"
        "|javafontshelper|getFontList)"
        "*"
Replace = "\0{ var fonts = "No Flash or Java fonts detected";"
          "return fonts;}"

BTW, 'fingerprinting' machines is not new.
Add Thank You Quote this message in a reply
Dec. 03, 2010, 08:21 AM
Post: #3
RE: Protecting identity - blocking System Fonts info
Thank you for providing the code Smile! I've tried it and, unfortunately, it doesn't block the font info. Data comes via Flash (as page says).

Here is some additional info that may help:
JS code, that we have to filter, is within an external file (in this particular case, it's "fetch_whorls.js", but, of cause, it could be have any other name). I hope we can filter scripts loaded from external files too, right? I don't know how to check / see the resulting JavaScript code that is actually active after the page was filtered and the HTML code is rendered. Thus, the only criteria for me now is to watch the result... Smile!

BTW, how do you see the active JavaScript code? Do you use some tool (JS debugger?) in FF? I'm running IE and so far I'm clueless in a way how to debug it Wink

I'm not an expert in Flash and Java neither, but I guess that the names "flashfontshelper" and "javafontshelper" could be arbitrary. From the other side, I tend to believe that names "user_fonts" (name of Flash internal variable) and "getFontList" (name of Java function) are predefined and, therefore, can't be easily changed (and that's what we need). Thus, my bet is on the latter two. But you may be right with searching for former couple of names too...

Here is info how to get font data with Flash:
<a href="http://www.maratz.com/blog/archives/2006/08/18/detect-visitors-fonts-with-flash/">Detect visitor’s fonts with Flash | maratz.com</a>

And here is info for getFontList() in Java:
<a href="http://download.oracle.com/javase/1.5.0/docs/api/java/awt/Toolkit.html#getFontList()">getFontList()</a>
and because "getFontList()" becomes deprecated, here is new function recommended for that purpose:
<a href="http://download.oracle.com/javase/1.5.0/docs/api/java/awt/GraphicsEnvironment.html#getAvailableFontFamilyNames()">getAvailableFontFamilyNames()</a>
Both are from " GraphicsEnvironment (Java 2 Platform SE 5.0)".

And finally, I agree that disabling flash and java is the only way to be sure this info is not shared. But I'd rather consider it as a last resort. And when it comes to the fact that the nosey sites will know that flash and java are disabled, I'd say - that's the goal! Smile! Let them know that they will have trouble dealing with us Big Teeth.
Add Thank You Quote this message in a reply
Dec. 03, 2010, 09:25 PM
Post: #4
RE: Protecting identity - blocking System Fonts info
The filter appears to work for me. That is it sets the value of the variable "fonts" and causes the web page to display "No Flash or Java fonts detected" regardless of the browser's settings. The other variables are not modified by the filter.


.gif  panopticlick.gif (Size: 18.79 KB / Downloads: 867)

You may have to beat on IE to make it let go of its cached copy of the external script or your Proxo may be choosing to not filter this external script.

Does the filter work in the Proxomitron's test window?

To debug while using sidki's set try loading http://panopticlick.eff.org/resources/fetch_whorls.js?prx-command=dbug..
Otherwise, enable "HTML Debug info" in the Proxomitron's log window and load http://panopticlick.eff.org/resources/fetch_whorls.js .
The Proxomitron's URL based commands no longer work in IE or you could also use something like http://px.dbug..panopticlick.eff.org/resources/fetch_whorls.js .

I agree to getFontList() and getAvailableFontFamilyNames() being predefined but I doubt that it matters.

Couldn't the author of the flash or java applet copy the info in the predefined variable to another flash or java variable and use the copy's name to pass the info to javascript?

Must a nosey site transfer the info to javascript before it can access it?

(Dec. 03, 2010 08:21 AM)OZO Wrote:  And when it comes to the fact that the nosey sites will know that flash and java are disabled, I'd say - that's the goal! Smile! Let them know that they will have trouble dealing with us Big Teeth.

And if the idea is to stop 'fingerprinting'...
Most people probably have flash, java, and javascript enabled.
Most people with flash and|or java and javascript enabled show some fonts.
People with browsers that execute flash and|or java but have no fonts via javascript are probably very few in number ( and probably filtering ads ).
Add Thank You Quote this message in a reply
Dec. 04, 2010, 06:03 AM
Post: #5
RE: Protecting identity - blocking System Fonts info
Excellent! It's working like a charm Smile!. Thank you!

I think it was my fault that I did not flush the TIF cache (I usually do it all the time). Sorry for the misinformation from my side.

I'd suggest some small changes in the filter:
1. adding new function "getAvailableFontFamilyNames", that will replace the old and deprecated "getFontList"
2. instead of returning the string "No Flash or Java fonts detected" (which could be used to ID browser), just to return nothing.

Here is modified code:
Code:
Name = "Blocking System Fonts info     10.12.04 (multi) [jjoe ozo] (d.s)"
Active = TRUE
Bounds = "function\s\w \{$INEST(\{,\})\}"
Limit = 1024
Match = "(\0\{)+{1}*"
        "(flashfontshelper|user_fonts"
        "|javafontshelper|getFontList|getAvailableFontFamilyNames)"
        "*"
Replace = "\0{ return; }"
Please feel free to modify it as you wish (especially in the "Name" to meet a conventional way to do it). But I guess, we're close to the point of offering a working filter. Smile!

And thank you for the hints on how to see JS debug info. I've tried both ways and it's working well with IE Smile!
Add Thank You Quote this message in a reply
Dec. 05, 2010, 08:22 PM
Post: #6
RE: Protecting identity - blocking System Fonts info
Code:
Name = "Blocking System Fonts info     10.12.04 (multi) [jjoe ozo] (d.s)"

(multi) refers to the ability of filters to match this filter's output. It is enabled by the "Allow for multiple matches" switch and shows in a filter's code as "Multi = TRUE".
The ".s" means site specific. ATM, this filter is not site or even type specific.
There should also be something that says the filter is not in a published set. I have used "Add" for new filters and "Mod" for existing filters.

So for now, how about

Code:
[Patterns]
Name = "Blocking System Fonts info     10.12.04 [jjoe ozo] ADD"
Active = TRUE
URL = "$TYPE(htm)|$TYPE(js)"
Bounds = "function\s\w \{$INEST(\{,\})\}"
Limit = 1024
Match = "(\0\{)+{1}*"
        "(flashfontshelper|user_fonts"
        "|javafontshelper|getFontList|getAvailableFontFamilyNames)"
        "*"
Replace = "\0{ return; }"

(Dec. 04, 2010 06:03 AM)OZO Wrote:  2. instead of returning the string "No Flash or Java fonts detected" (which could be used to ID browser), just to return nothing.

I don't understand. Wouldn't returning an expected string be better?
My guess is that more browsers get "No Flash or Java fonts detected" than those that get nothing or "undefined". When my browser got "undefined", panopticlick reported one in 257253. However, a more sophisticated filter would be needed to try to always return the 'expected' string.

Also, I think it may be possible to score well in each indivual test and still be very unique.


While I'd rather not be watched and if I cared, I'd like to know which sites are watching for some of these things, stop them, and then decide what to do about it.

I've added the following code to the bottom of AdKeys-J

Code:
# System fonts
get_fonts &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
flashfontshelper(^$TST(\3=[n1s])) &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
/:user_fonts(^$TST(\3=[n1s])) &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
user_fonts(^$TST(\3=[n1s])) &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
javafontshelper(^$TST(\3=[n1s])) &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
getFontList \(\)(^$TST(\3=[n1s])) &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
getAvailableFontFamilyNames \(\)(^$TST(\3=[n1s])) &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)

# Browser Plugins
plugins(^ \[) &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
PluginDetect &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
getVersion\(*\) &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)

#Adobe version
oAcro &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)

#Dom Storage
localStorage &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)
sessionStorage &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)

#Dom Storage
oPersistDiv &&\8 &$ADDLST(Log-Rare,AKEY-Jn \t\8 \t\u)

I'll see what I catch.

Curent Log-Rare hits are

Code:
AKEY-Jn     plugins     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     plugins     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     plugins      http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     oAcro     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     oAcro     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     oAcro     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     get_fonts     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     /:user_fonts     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     javafontshelper     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     sessionStorage     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     localStorage     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     sessionStorage     http://panopticlick.eff.org/resources/fetch_whorls.js
AKEY-Jn     oPersistDiv     http://panopticlick.eff.org/resources/fetch_whorls.js
Add Thank You Quote this message in a reply
Dec. 06, 2010, 06:51 AM
Post: #7
RE: Protecting identity - blocking System Fonts info
Thank you for clarification regarding to Name sting. I agree with the change. Let's keep that code:
Code:
[Patterns]
Name = "Blocking System Fonts info     10.12.04 [jjoe ozo] ADD"
Active = TRUE
URL = "$TYPE(htm)|$TYPE(js)"
Bounds = "function\s\w \{$INEST(\{,\})\}"
Limit = 1024
Match = "(\0\{)+{1}*"
        "(flashfontshelper|user_fonts"
        "|javafontshelper|getFontList|getAvailableFontFamilyNames)"
        "*"
Replace = "\0{ return; }"
Just want to double check, the line 'URL = "$TYPE(htm)|$TYPE(js)"' includes HTML files as well. Right?

(Dec. 05, 2010 08:22 PM)JJoe Wrote:  
(Dec. 04, 2010 06:03 AM)OZO Wrote:  2. instead of returning the string "No Flash or Java fonts detected" (which could be used to ID browser), just to return nothing.
I don't understand. Wouldn't returning an expected string be better?
My guess is that more browsers get "No Flash or Java fonts detected" than those that get nothing or "undefined". When my browser got "undefined", panopticlick reported one in 257253. However, a more sophisticated filter would be needed to try to always return the 'expected' string.
Right. The purpose of the filter is to prevent some nosey sites from getting system fonts info, not to display a well formatted and meaningful message on "panopticlick.eff.org" site (or even try to get the best score there Wink).

Nosey sites will not let us know about what this function returns. They just send collected info silently to a remote server without anyone's permission. Thus, there is no any need to return a meaningfull string. I'm sure that even if we throw an exception there, properly developed tracking script will react accordingly (silently) Wink

(Dec. 05, 2010 08:22 PM)JJoe Wrote:  While I'd rather not be watched and if I cared, I'd like to know which sites are watching for some of these things, stop them, and then decide what to do about it.

I've added the following code to the bottom of AdKeys-J
Good idea. But I'd rather not count on names of functions and variables that one particular site is using, but rather watch for function names (and variables) that come from libraries, known plugins, ActiveX controls, Flash and Java toolkits...

From this point of view I don't see a value in adding these names to watch / remove (in AdKeys-J):
get_fonts - local function name, it could vary easily
oAcro - local variable, I'd rather watch for the name "PDF.PdfCtrl" instead. They can't change that name easily
oPersistDiv - I don't know where the name of the variable comes from, but I assume it's local (thus could vary greatly)
plugins - a local name
...

Again, the goal is not to make protection from this particular test site (or other similar test sites), but rather to find out what could be used for that purpose and block common ways of getting tracking info by nosey sites.

BTW, how do you manage the content in "Log-Rare.log" file. To remove extra lines you have to kill Proxo, edit the log file and then restart Proxo again. Right? Is it the only way? (I assume, it is)
Add Thank You Quote this message in a reply
Dec. 06, 2010, 11:20 PM
Post: #8
RE: Protecting identity - blocking System Fonts info
(Dec. 06, 2010 06:51 AM)OZO Wrote:  Just want to double check, the line 'URL = "$TYPE(htm)|$TYPE(js)"' includes HTML files as well. Right?

Yes but there needs to be a Bounds Match change.

Code:
[Patterns]
Name = "Blocking System Fonts info     10.12.06 [jjoe ozo] ADD"
Active = TRUE
URL = "$TYPE(htm)|$TYPE(js)"
Bounds = "function(\(\))+\s(*\{)+{1}$INEST(\{,\})\}"
Limit = 1024
Match = "(\0\{)+{1}*"
        "(flashfontshelper|user_fonts"
        "|javafontshelper|getFontList|getAvailableFontFamilyNames)"
        "*"
Replace = "\0{ return; }"

and keyword addition to cover the method used by Henrik Gemal at http://browserspy.dk/fonts-flash.php .

The code to match seems to be

Code:
function fontList(aFonts) {
            var fontdetail = 0;
            if (typeof(aFonts) == "string") {
                var fonts = aFonts.split(",");
                $("#fontsnum").text(fonts.length);
                $("#fontslist").text("Please wait while list of font are bing generated...");
                if (fontdetail) {
                    var rows = getFontRows(fonts);
                    $("#fontslistrow").hide();
                    $("#fontsbody").append(rows);
                } else {
                    $("#fontslist").text("");
                    for (var i = 0; i < fonts.length; i++) {
                        $("#fontslist").append(fonts[i] + "<br/>");
                    }
                }
                fontsok = true;
            } else {
                $("#fontsnum").html("Flash doesn't seems to be installed or working! <a href=\"flash.php\">Check Flash</a>.");
                $("#fontslist").html("Flash doesn't seems to be installed or working! <a href=\"flash.php\">Check Flash</a>.");
            }
        }

I'll allow you to choose the keyword. Wink


Sorry to be a pain but...

Subject: Remote access to the names of flash and java fonts
Object: Get in the way.
Reason: Very few sites need these names. The names may allow sites to target machines for tracking (or other unwanted behaviour).
Method: Attempt to alter the javascripts that some sites use to gather the names.
Caveat1: Filter may fail to match because there are many, many ways to write the scripts that gather this info.
Caveat2: Some javascripts may be obfuscated and thus may not be altered by the Proxomitron.
Caveat3: Altering or blocking javascripts may allow sites to target machines for tracking (or other unwanted behaviour).

This set already has filters that block obfuscated code. The flash and java toggle filters may hide these names. So the caveats don't bother me as they already exist but I do believe they exist.

Always consider published solutions. Some evil webmasters are lazy and just copy.
Plugins is working well, too well. One false positive at yahoo.
I think things like oAcro, oPersistDiv, o... are Microsoft, http://msdn.microsoft.com/en-us/library/...S.85).aspx .
http://www.pinlady.net/PluginDetect/

(Dec. 06, 2010 06:51 AM)OZO Wrote:  BTW, how do you manage the content in "Log-Rare.log" file. To remove extra lines you have to kill Proxo, edit the log file and then restart Proxo again. Right? Is it the only way? (I assume, it is)

Open the Proxomitron's system tray menu, "Edit Blockfile", and then click on Log-Rare. Make your changes and save before the Proxomitron reclaims the file.

http://www.proxomitron.info/45/help/System%20Tray.html

Dinner
Add Thank You Quote this message in a reply
Dec. 07, 2010, 08:57 AM (This post was last modified: Dec. 07, 2010 09:05 AM by OZO.)
Post: #9
RE: Protecting identity - blocking System Fonts info
OK, then. Let's keep v.10.12.06 as a working copy. Smile!

With regards to Henrik Gemal and his method at http://browserspy.dk/fonts-flash.php - it actually uses the same code to get list of system fonts (obj.GetVariable("/:user_fonts")). It's here:
Code:
$(document).oneTime(4000, function() {
  if (!fontsok) {
    var fonts = false;
    var obj = document.getElementById("fontshelper");
    if (typeof(obj.GetVariable) != "undefined") {
      fonts = obj.GetVariable("/:user_fonts");
    }
    fontList(fonts);
  }
});
So, this filter could help here too.

I agree with your summary about what we try to do here. Of cause it's not 100% reliable and the cat/mouse rule applies... But it's better to do what we can then, then do nothing. And I'm sure you think the same way too.

Regarding to "Altering or blocking javascripts may allow sites to target machines for tracking (or other unwanted behaviour)." I'd say - they're welcome to do so! Let them detect and the more they discover that current user base using protective measures, the more they may start to think if those tracking techniques are cost effective... These days many folks around just block JavaScript visiting unknown sites (I'm not among them, but I see clear the tendency now). So, blocking JavaScripts is not something unique that comes only from Proxo users. Again the more they discover such things - the better...

Thank you for the hint how to edit log files on a fly. I appreciate that and the great help with making the filter Smile!

BTW, my list of System Fonts contains 123 items! How more unique it could be?! It's like an GUID created on my side... Now it's all gone!!! Thumbs Up
Add Thank You Quote this message in a reply
Dec. 07, 2010, 01:04 PM
Post: #10
RE: Protecting identity - blocking System Fonts info
(Dec. 07, 2010 08:57 AM)OZO Wrote:  With regards to Henrik Gemal and his method at http://browserspy.dk/fonts-flash.php - it actually uses the same code to get list of system fonts (obj.GetVariable("/:user_fonts")).

Did you only test with IE?
Add Thank You Quote this message in a reply
Dec. 08, 2010, 03:43 AM
Post: #11
RE: Protecting identity - blocking System Fonts info
Yes. That's my primary browser, so far...
Add Thank You Quote this message in a reply
Dec. 08, 2010, 03:06 PM
Post: #12
RE: Protecting identity - blocking System Fonts info
The filter "Blocking System Fonts info 10.12.04 [jjoe ozo] ADD" does not stop the display of fonts at http://browserspy.dk/fonts-flash.php when I use Mozilla, Opera, or Chrome.
Add Thank You Quote this message in a reply
Dec. 09, 2010, 05:22 AM
Post: #13
RE: Protecting identity - blocking System Fonts info
I've just tested this code (old, not anything new here) with IE7, FF.3.6.10 and Iron.7.0.520:
Code:
Name = "Blocking System Fonts info     10.12.06 [jjoe ozo] ADD"
Active = TRUE
URL = "$TYPE(htm)|$TYPE(js)"
Bounds = "function(\(\))+\s(*\{)+{1}$INEST(\{,\})\}"
Limit = 1024
Match = "(\0\{)+{1}*"
        "(flashfontshelper|user_fonts"
        "|javafontshelper|getFontList|getAvailableFontFamilyNames)"
        "*"
Replace = "\0{ return; }"
And in all cases page (http://browserspy.dk/fonts-flash.php) was just stuck with this message:
Code:
Number of fonts installed    Please wait while Flash is loaded and executed...
List of fonts installed      Please wait while Flash is loaded and executed...
No any system fonts were displayed...

There is no any modification in my "AdKeys-J", in case if that matters.
Add Thank You Quote this message in a reply
Dec. 09, 2010, 02:36 PM
Post: #14
RE: Protecting identity - blocking System Fonts info
Are you allowing the flash to run?

I see what you see before I activate the flash toggle.

.gif  BeforeFlash.gif (Size: 8.89 KB / Downloads: 706)

The list of fonts is displayed after the flash runs.

.gif  AfterFlash.gif (Size: 16.5 KB / Downloads: 715)
Add Thank You Quote this message in a reply
Dec. 09, 2010, 09:19 PM
Post: #15
RE: Protecting identity - blocking System Fonts info
In IE7 I do allow Flash to run. In FF and Iron there is no prompt for that (no "Flash" cyan rectangle).
Here is what I see in debugging log:
Code:
<Match: Blocking System Fonts info     10.12.06 [jjoe ozo] ADD >
function() {
            if (!fontsok) {
                var fonts = false;
                var obj = document.getElementById("fontshelper");
                if (typeof(obj.GetVariable) != "undefined") {
                    fonts = obj.GetVariable("/:user_fonts");
                }
                fontList(fonts);
            }
        }
</Match>
function() { return; });
Add Thank You Quote this message in a reply
Post Reply 


Forum Jump: