summaryrefslogtreecommitdiffstats
path: root/tests/selenium/fingerprinting_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/selenium/fingerprinting_test.py')
-rw-r--r--tests/selenium/fingerprinting_test.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/tests/selenium/fingerprinting_test.py b/tests/selenium/fingerprinting_test.py
new file mode 100644
index 0000000..0fadd2b
--- /dev/null
+++ b/tests/selenium/fingerprinting_test.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import unittest
+
+import pbtest
+
+from functools import partial
+
+from pbtest import retry_until
+
+
+class FingerprintingTest(pbtest.PBSeleniumTest):
+ """Tests to make sure fingerprinting detection works as expected."""
+
+ def detected_fingerprinting(self, domain):
+ return self.js("""let tracker_origin = window.getBaseDomain("{}");
+let tabData = chrome.extension.getBackgroundPage().badger.tabData;
+return (
+ Object.keys(tabData).some(tab_id => {{
+ let fpData = tabData[tab_id].fpData;
+ return fpData &&
+ fpData.hasOwnProperty(tracker_origin) &&
+ fpData[tracker_origin].canvas &&
+ fpData[tracker_origin].canvas.fingerprinting === true;
+ }})
+);""".format(domain))
+
+ def detected_tracking(self, domain, page_url):
+ return self.js("""let tracker_origin = window.getBaseDomain("{}"),
+ site_origin = window.getBaseDomain((new URI("{}")).host),
+ map = chrome.extension.getBackgroundPage().badger.storage.snitch_map.getItemClones();
+
+return (
+ map.hasOwnProperty(tracker_origin) &&
+ map[tracker_origin].indexOf(site_origin) != -1
+);""".format(domain, page_url))
+
+ def get_fillText_source(self):
+ return self.js("""
+ const canvas = document.getElementById("writetome");
+ const ctx = canvas.getContext("2d");
+ return ctx.fillText.toString();
+ """)
+
+ def setUp(self):
+ # enable local learning
+ self.load_url(self.options_url)
+ self.wait_for_script("return window.OPTIONS_INITIALIZED")
+ self.find_el_by_css('#local-learning-checkbox').click()
+
+ # TODO can fail because our content script runs too late: https://crbug.com/478183
+ @pbtest.repeat_if_failed(3)
+ def test_canvas_fingerprinting_detection(self):
+ FIXTURE_URL = (
+ "https://efforg.github.io/privacybadger-test-fixtures/html/"
+ "fingerprinting.html"
+ )
+ FINGERPRINTING_DOMAIN = "cdn.jsdelivr.net"
+
+ # clear pre-trained/seed tracker data
+ self.load_url(self.options_url)
+ self.js("chrome.extension.getBackgroundPage().badger.storage.clearTrackerData();")
+
+ # visit the page
+ self.load_url(FIXTURE_URL)
+
+ # now open a new window (to avoid clearing badger.tabData)
+ # and verify results
+ self.open_window()
+
+ # check that we detected the fingerprinting domain as a tracker
+ self.load_url(self.options_url)
+ # TODO unnecessary retrying?
+ self.assertTrue(
+ retry_until(partial(self.detected_tracking, FINGERPRINTING_DOMAIN, FIXTURE_URL)),
+ "Canvas fingerprinting resource was detected as a tracker.")
+
+ # check that we detected canvas fingerprinting
+ self.assertTrue(
+ self.detected_fingerprinting(FINGERPRINTING_DOMAIN),
+ "Canvas fingerprinting resource was detected as a fingerprinter."
+ )
+
+ # Privacy Badger overrides a few functions on canvas contexts to check for fingerprinting.
+ # In previous versions, it would restore the native function after a single call. Unfortunately,
+ # this would wipe out polyfills that had also overridden the same functions, such as the very
+ # popular "hidpi-canvas-polyfill".
+ def test_canvas_polyfill_clobbering(self):
+ FIXTURE_URL = (
+ "https://efforg.github.io/privacybadger-test-fixtures/html/"
+ "fingerprinting_canvas_hidpi.html"
+ )
+
+ # visit the page
+ self.load_url(FIXTURE_URL)
+
+ # check that we did not restore the native function (should be hipdi polyfill)
+ self.assertNotIn("[native code]", self.get_fillText_source(),
+ "Canvas context fillText is not native version (polyfill has been retained)."
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()