def test_no_dnt_header_when_disabled(self): TEST_URL = "https://httpbin.org/get" self.disable_badger_on_site(TEST_URL) headers = retry_until(partial(self.get_first_party_headers, TEST_URL), times=8) self.assertTrue(headers is not None, "It seems we failed to get DNT headers") self.assertNotIn('Dnt', headers, "DNT header should have been missing")
def test_canvas_fingerprinting_detection(self): PAGE_URL = ( "https://gitcdn.link/cdn/ghostwords/" "ff6347b93ec126d4f73a9ddfd8b09919/raw/6b215b3f052115d36831ecfca758081ca7da7e37/" "privacy_badger_fingerprint_test_fixture.html" ) FINGERPRINTING_DOMAIN = "cdn.jsdelivr.net" # open Badger's background page self.load_url(self.bg_url) # need to keep Badger's background page open for tabData to persist # so, open and switch to a new window self.open_window() # visit the page self.load_url(PAGE_URL) # switch back to Badger's background page switch_to_window_with_url(self.driver, self.bg_url) # check that we detected the fingerprinting domain as a tracker self.assertTrue( retry_until(partial(self.detected_tracking, FINGERPRINTING_DOMAIN, PAGE_URL)), "Canvas fingerprinting resource was detected as a tracker.") # check that we detected canvas fingerprinting self.assertTrue( self.detected_fingerprinting(FINGERPRINTING_DOMAIN), "Canvas fingerprinting resources was detected as a fingerprinter." )
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.")
def test_canvas_fingerprinting_detection(self): PAGE_URL = "https://www.eff.org/files/badger_test_fixtures/fingerprinting.html" FINGERPRINTING_DOMAIN = "cdn.jsdelivr.net" # open Badger's background page self.load_url(self.bg_url) # need to keep Badger's background page open for tabData to persist # so, open and switch to a new window self.open_window() # visit the page self.load_url(PAGE_URL) # switch back to Badger's background page switch_to_window_with_url(self.driver, self.bg_url) # check that we detected the fingerprinting domain as a tracker self.assertTrue( retry_until( partial(self.detected_tracking, FINGERPRINTING_DOMAIN, PAGE_URL)), "Canvas fingerprinting resource was detected as a tracker.") # check that we detected canvas fingerprinting self.assertTrue( self.detected_fingerprinting(FINGERPRINTING_DOMAIN), "Canvas fingerprinting resources was detected as a fingerprinter.")
def test_canvas_fingerprinting_detection(self): PAGE_URL = ( "https://cdn.rawgit.com/ghostwords" "/ff6347b93ec126d4f73a9ddfd8b09919/raw/2332f82d3982bd4a84cd2380aed90228955d1f2a" "/privacy_badger_fingerprint_test_fixture.html" ) FINGERPRINTING_DOMAIN = "cdn.jsdelivr.net" # open Badger's background page self.load_url(self.bg_url) # need to keep Badger's background page open for tabData to persist # so, either open and switch to a new window, # or just reuse the already-open new user welcome window switch_to_window_with_url(self.driver, self.first_run_url) # visit the page self.load_url(PAGE_URL) # switch back to Badger's background page switch_to_window_with_url(self.driver, self.bg_url) # check that we detected the fingerprinting domain as a tracker self.assertTrue( retry_until(partial(self.detected_tracking, FINGERPRINTING_DOMAIN, PAGE_URL)), "Canvas fingerprinting resource was detected as a tracker.") # check that we detected canvas fingerprinting self.assertTrue( self.detected_fingerprinting(FINGERPRINTING_DOMAIN), "Canvas fingerprinting resources was detected as a fingerprinter." )
def test_canvas_fingerprinting_detection(self): PAGE_URL = ( "https://gitcdn.link/cdn/ghostwords/" "ff6347b93ec126d4f73a9ddfd8b09919/raw/6b215b3f052115d36831ecfca758081ca7da7e37/" "privacy_badger_fingerprint_test_fixture.html") FINGERPRINTING_DOMAIN = "cdn.jsdelivr.net" # open Badger's background page self.load_url(self.bg_url) # need to keep Badger's background page open for tabData to persist # so, open and switch to a new window self.open_window() # visit the page self.load_url(PAGE_URL) # switch back to Badger's background page switch_to_window_with_url(self.driver, self.bg_url) # check that we detected the fingerprinting domain as a tracker self.assertTrue( retry_until( partial(self.detected_tracking, FINGERPRINTING_DOMAIN, PAGE_URL)), "Canvas fingerprinting resource was detected as a tracker.") # check that we detected canvas fingerprinting self.assertTrue( self.detected_fingerprinting(FINGERPRINTING_DOMAIN), "Canvas fingerprinting resources was detected as a fingerprinter.")
def test_ga_js_surrogate(self): # verify the surrogate is present self.load_url(self.options_url) self.assertTrue( self. js("let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "return sdb.hostnames.hasOwnProperty('www.google-analytics.com');" ), "Surrogate is missing but should be present.") # verify site loads self.assertTrue(self.load_ga_js_test_page(), "Page failed to load even before we did anything.") # block ga.js (known to break the site) self.load_url(self.options_url) # also back up the surrogate definition before removing it ga_backup = self.js( "let bg = chrome.extension.getBackgroundPage();" "bg.badger.heuristicBlocking.blacklistOrigin('www.google-analytics.com', 'google-analytics.com');" "const sdb = bg.require('surrogatedb');" "return JSON.stringify(sdb.hostnames['www.google-analytics.com']);" ) # now remove the surrogate self.js("let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "delete sdb.hostnames['www.google-analytics.com'];") # wait until this happens self.wait_for_script( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "return !sdb.hostnames.hasOwnProperty('www.google-analytics.com');", timeout=5, message="Timed out waiting for surrogate to get removed.") # verify site breaks self.assertFalse( self.load_ga_js_test_page(), "Page loaded successfully when it should have failed.") # re-enable surrogate self.load_url(self.options_url) self.js( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "sdb.hostnames['www.google-analytics.com'] = JSON.parse('%s');" % ga_backup) # wait until this happens self.wait_for_script( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "return sdb.hostnames.hasOwnProperty('www.google-analytics.com');", timeout=5, message="Timed out waiting for surrogate to get readded.") # verify site loads again self.assertTrue(retry_until(self.load_ga_js_test_page), "Page failed to load after surrogation.")
def test_first_party_dnt_header(self): TEST_URL = "https://httpbin.org/get" headers = retry_until(partial(self.get_first_party_headers, TEST_URL)) self.assertTrue(headers is not None, "It seems we failed to get DNT headers") self.assertIn('Dnt', headers, "DNT header should have been present") self.assertEqual(headers['Dnt'], "1", 'DNT header should have been set to "1"')
def test_no_dnt_header_when_disabled(self): TEST_URL = "https://httpbin.org/get" self.disable_badger_on_site(TEST_URL) headers = retry_until(partial(self.get_first_party_headers, TEST_URL)) self.assertTrue(headers is not None, "It seems we failed to get DNT headers") self.assertNotIn('Dnt', headers, "DNT header should have been missing")
def test_dnt_check_should_happen_for_blocked_domains(self): PAGE_URL = ( "https://gitcdn.link/cdn/ghostwords/" "74585c942a918509b20bf2db5659646e/raw/2401659e678442de6309339882f19fbb21dbc959/" "privacy_badger_dnt_test_fixture.html" ) DNT_DOMAIN = "www.eff.org" BLOCK_DOMAIN_JS = ( "(function () {" "chrome.extension.getBackgroundPage()." "badger.storage.setupHeuristicAction(" " arguments[0]," " chrome.extension.getBackgroundPage().constants.BLOCK" ");" "}());" ) # mark a DNT-compliant domain for blocking self.load_url(self.options_url) self.js(BLOCK_DOMAIN_JS, DNT_DOMAIN) # visit a page that loads a resource from that DNT-compliant domain self.open_window() self.load_url(PAGE_URL) # switch back to Badger's options page switch_to_window_with_url(self.driver, self.options_url) # verify that the domain is blocked self.assertTrue(self.domain_was_detected(DNT_DOMAIN), msg="Domain should have been detected.") self.assertTrue(self.domain_was_blocked(DNT_DOMAIN), msg="DNT-compliant resource should have been blocked at first.") def reload_and_see_if_unblocked(): # switch back to the page with the DNT-compliant resource switch_to_window_with_url(self.driver, PAGE_URL) # reload it self.load_url(PAGE_URL) # switch back to Badger's options page switch_to_window_with_url(self.driver, self.options_url) return ( self.domain_was_detected(DNT_DOMAIN) and self.domain_was_blocked(DNT_DOMAIN) ) # verify that the domain is allowed was_blocked = retry_until( reload_and_see_if_unblocked, tester=lambda x: not x, msg="Waiting a bit for DNT check to complete and retrying ...") self.assertFalse(was_blocked, msg="DNT-compliant resource should have gotten unblocked.")
def test_dnt_check_should_happen_for_blocked_domains(self): PAGE_URL = ( "https://gistcdn.githack.com/ghostwords/" "74585c942a918509b20bf2db5659646e/raw/2401659e678442de6309339882f19fbb21dbc959/" "privacy_badger_dnt_test_fixture.html") DNT_DOMAIN = "www.eff.org" BLOCK_DOMAIN_JS = ( "(function () {" "chrome.extension.getBackgroundPage()." "badger.storage.setupHeuristicAction(" " arguments[0]," " chrome.extension.getBackgroundPage().constants.BLOCK" ");" "}());") # mark a DNT-compliant domain for blocking self.load_url(self.options_url) self.js(BLOCK_DOMAIN_JS, DNT_DOMAIN) # visit a page that loads a resource from that DNT-compliant domain self.open_window() self.load_url(PAGE_URL) # switch back to Badger's options page switch_to_window_with_url(self.driver, self.options_url) # verify that the domain is blocked self.assertTrue(self.domain_was_detected(DNT_DOMAIN), msg="Domain should have been detected.") self.assertTrue( self.domain_was_blocked(DNT_DOMAIN), msg="DNT-compliant resource should have been blocked at first.") def reload_and_see_if_unblocked(): # switch back to the page with the DNT-compliant resource switch_to_window_with_url(self.driver, PAGE_URL) # reload it self.load_url(PAGE_URL) # switch back to Badger's options page switch_to_window_with_url(self.driver, self.options_url) return (self.domain_was_detected(DNT_DOMAIN) and self.domain_was_blocked(DNT_DOMAIN)) # verify that the domain is allowed was_blocked = retry_until( reload_and_see_if_unblocked, tester=lambda x: not x, msg="Waiting a bit for DNT check to complete and retrying ...") self.assertFalse( was_blocked, msg="DNT-compliant resource should have gotten unblocked.")
def test_should_detect_ls_of_third_party_frame(self): # TODO We get some intermittent failures for this test. # It seems we sometimes miss the setting of localStorage items, # perhaps because the script runs before we start intercepting the calls. # Perhaps related to: https://github.com/ghostwords/chameleon/issues/5 self.load_url("https://rawgit.com/gunesacar/24d81a5c964cb563614162c264be32f0/raw/8fa10f97b87343dfb62ae9b98b753c73a995157e/frame_ls.html") # TODO might also be related to https://github.com/EFForg/privacybadger/pull/1522 time.sleep(1) self.assertTrue(pbtest.retry_until( partial(self.detected_tracking_by, "githack.com"), times=2))
def test_should_detect_ls_of_third_party_frame(self): self.load_url( "https://www.eff.org/files/badger_test_fixtures/localstorage.html") # TODO We get some intermittent failures for this test. # It seems we sometimes miss the setting of localStorage items # because the script runs after we already checked what's in localStorage. # We can work around this race condition by reloading the page. self.driver.refresh() self.assertEqual( pbtest.retry_until(partial(self.get_snitch_map_for, "githack.com"), times=3), ["eff.org"])
def test_first_party_dnt_header(self): TEST_URL = "https://httpbin.org/get" self.load_url(self.bg_url) # wait until DNT-injecting webRequest listeners have been registered self.wait_for_script("return badger.INITIALIZED") headers = retry_until(partial(self.get_first_party_headers, TEST_URL), times=8) self.assertTrue(headers is not None, "It seems we failed to get DNT headers") self.assertIn('Dnt', headers, "DNT header should have been present") self.assertEqual(headers['Dnt'], "1", 'DNT header should have been set to "1"')
def test_dnt_check_should_happen_for_blocked_domains(self): PAGE_URL = ( "https://cdn.rawgit.com/ghostwords/" "74585c942a918509b20bf2db5659646e/raw/f42d25717e5b4f735c7affa527a2e0b62286c005/" "privacy_badger_dnt_test_fixture.html") DNT_DOMAIN = "www.eff.org" BLOCK_DOMAIN_JS = """(function () {{ badger.storage.setupHeuristicAction('{}', constants.BLOCK); }}());""".format(DNT_DOMAIN) # mark a DNT-compliant domain for blocking self.load_url(self.bg_url) self.js(BLOCK_DOMAIN_JS) # need to keep Badger's background page open for our changes to persist # so, either open and switch to a new window, # or just reuse the already-open new user welcome window switch_to_window_with_url(self.driver, self.first_run_url) # visit a page that loads a resource from that DNT-compliant domain self.load_url(PAGE_URL) # switch back to Badger's background page switch_to_window_with_url(self.driver, self.bg_url) # verify that the domain is blocked self.assertTrue( self.domain_was_blocked(DNT_DOMAIN), msg="DNT-compliant resource should have been blocked at first.") def reload_and_see_if_unblocked(): # switch back to the page with the DNT-compliant resource switch_to_window_with_url(self.driver, PAGE_URL) # reload it self.load_url(PAGE_URL) # switch back to Badger's background page switch_to_window_with_url(self.driver, self.bg_url) return self.domain_was_blocked(DNT_DOMAIN) # verify that the domain is allowed was_blocked = retry_until( reload_and_see_if_unblocked, tester=lambda x: not x, msg="Waiting a bit for DNT check to complete and retrying ...") self.assertFalse( was_blocked, msg="DNT-compliant resource should have gotten unblocked.")
def test_ga_js_surrogate(self): SURROGATE_HOST = "www.google-analytics.com" # clear pre-trained/seed tracker data self.load_url(self.options_url) self.js( "chrome.extension.getBackgroundPage().badger.storage.clearTrackerData();" ) # verify the surrogate is present self.load_url(self.options_url) assert self.js( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" f"return sdb.hostnames.hasOwnProperty('{SURROGATE_HOST}');" ), "surrogate is missing but should be present" # verify site loads assert self.load_ga_js_fixture(), ( "page failed to load even before we did anything") # block ga.js (known to break the site) self.block_domain(SURROGATE_HOST) # back up the surrogate definition before removing it ga_backup = self.js( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" f"return JSON.stringify(sdb.hostnames['{SURROGATE_HOST}']);") # now remove the surrogate self.js("let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" f"delete sdb.hostnames['{SURROGATE_HOST}'];") # verify site breaks assert not self.load_ga_js_fixture(), ( "page loaded successfully when it should have failed") # re-enable surrogate self.open_window() self.load_url(self.options_url) self.js("(function () {" "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" f"let gaSurrogate = JSON.parse('{ga_backup}');" f"sdb.hostnames['{SURROGATE_HOST}'] = gaSurrogate;" "}());") # verify site loads again assert retry_until( self.load_ga_js_fixture), ("page failed to load after surrogation")
def test_unwrapping(self): self.perform_google_search() def _check_results(): # select all anchor elements with non-empty href attributes SELECTOR = "a[href]:not([href=''])" search_results = self.driver.find_elements_by_css_selector( SELECTOR) # remove "About this result" links as they do not get cleaned # (they don't match any of the `trap_link` selectors) # and so they fail the rel check below search_results = [ a for a in search_results if (a.text or a.get_attribute('textContent') != self.SEARCH_RESULT_URL or a.get_attribute('innerHTML') != self.SEARCH_RESULT_URL) ] # verify these appear to be actual search results hrefs = [link.get_attribute('href') for link in search_results] self.assertIn(self.SEARCH_RESULT_URL, hrefs, "At least one search result points to our homepage") # verify that tracking attributes are missing for link in search_results: # only check links that point to our homepage # as there is a mix of search result links and other links # and not all links get cleaned # and it's not clear how to select search result links only href = link.get_attribute('href') if self.SEARCH_RESULT_URL not in href: continue self.assertFalse(link.get_attribute('ping'), "Tracking attribute should be missing") self.assertFalse(link.get_attribute('onmousedown'), "Tracking attribute should be missing") self.assertEqual(link.get_attribute('rel'), "noreferrer noopener") return True time.sleep(1) self.assertTrue( pbtest.retry_until( pbtest.convert_exceptions_to_false(_check_results)), "Search results still fail our checks after several attempts")
def test_no_dnt_header_when_dnt_disabled(self): TEST_URL = "https://httpbin.org/get" self.load_url(self.options_url) self.wait_for_script("return window.OPTIONS_INITIALIZED") self.find_el_by_css('#enable_dnt_checkbox').click() headers = retry_until(partial(self.get_first_party_headers, TEST_URL), times=8) self.assertTrue(headers is not None, "It seems we failed to get headers") self.assertNotIn('Dnt', headers, "DNT header should have been missing") self.assertNotIn('Sec-Gpc', headers, "GPC header should have been missing")
def test_first_party_dnt_header(self): TEST_URL = "https://httpbin.org/get" # wait until DNT-injecting webRequest listeners have been registered self.wait_for_script( "return chrome.extension.getBackgroundPage().badger.INITIALIZED" ) headers = retry_until(partial(self.get_first_party_headers, TEST_URL), times=8) self.assertTrue(headers is not None, "It seems we failed to get DNT headers") self.assertIn('Dnt', headers, "DNT header should have been present") self.assertEqual(headers['Dnt'], "1", 'DNT header should have been set to "1"')
def test_should_detect_ls_of_third_party_frame(self): self.load_url( "https://gitcdn.link/cdn/gunesacar/" "24d81a5c964cb563614162c264be32f0/raw/8fa10f97b87343dfb62ae9b98b753c73a995157e/" "frame_ls.html") # TODO We get some intermittent failures for this test. # It seems we sometimes miss the setting of localStorage items # because the script runs after we already checked what's in localStorage. # We can work around this race condition by reloading the page. self.driver.refresh() self.assertEqual( pbtest.retry_until(partial(self.get_snitch_map_for, "githack.com"), times=3), ["gitcdn.link"])
def test_should_detect_ls_of_third_party_frame(self): # TODO We get some intermittent failures for this test. # It seems we sometimes miss the setting of localStorage items, # perhaps because the script runs before we start intercepting the calls. # Perhaps related to https://github.com/ghostwords/chameleon/issues/5 # Might also be related to https://github.com/EFForg/privacybadger/pull/1522 self.load_url( "https://gitcdn.link/cdn/gunesacar/" "24d81a5c964cb563614162c264be32f0/raw/8fa10f97b87343dfb62ae9b98b753c73a995157e/" "frame_ls.html") self.assertEqual( pbtest.retry_until(partial(self.get_snitch_map_for, "githack.com")), ["gitcdn.link"])
def test_should_detect_ls_of_third_party_frame(self): self.load_url( "https://gitcdn.link/cdn/gunesacar/" "24d81a5c964cb563614162c264be32f0/raw/8fa10f97b87343dfb62ae9b98b753c73a995157e/" "frame_ls.html" ) # TODO We get some intermittent failures for this test. # It seems we sometimes miss the setting of localStorage items # because the script runs after we already checked what's in localStorage. # We can work around this race condition by reloading the page. self.driver.refresh() self.assertEqual( pbtest.retry_until(partial(self.get_snitch_map_for, "githack.com"), times=3), ["gitcdn.link"] )
def test_dnt_policy_check_should_happen_for_blocked_domains(self): PAGE_URL = ( "https://efforg.github.io/privacybadger-test-fixtures/html/" "dnt.html") DNT_DOMAIN = "www.eff.org" # mark a DNT-compliant domain for blocking self.block_domain(DNT_DOMAIN) # visit a page that loads a resource from that DNT-compliant domain self.open_window() self.load_url(PAGE_URL) # switch back to Badger's options page self.switch_to_window_with_url(self.options_url) # verify that the domain is blocked self.assertTrue(self.domain_was_detected(DNT_DOMAIN), msg="Domain should have been detected.") self.assertTrue( self.domain_was_blocked(DNT_DOMAIN), msg="DNT-compliant resource should have been blocked at first.") def reload_and_see_if_unblocked(): # switch back to the page with the DNT-compliant resource self.switch_to_window_with_url(PAGE_URL) # reload it self.load_url(PAGE_URL) # switch back to Badger's options page self.switch_to_window_with_url(self.options_url) return (self.domain_was_detected(DNT_DOMAIN) and self.domain_was_blocked(DNT_DOMAIN)) # verify that the domain is allowed was_blocked = retry_until( reload_and_see_if_unblocked, tester=lambda x: not x, msg="Waiting a bit for DNT check to complete and retrying ...") self.assertFalse( was_blocked, msg="DNT-compliant resource should have gotten unblocked.")
def test_should_detect_ls_of_third_party_frame(self): FIRST_PARTY_BASE = "eff.org" THIRD_PARTY_BASE = "efforg.github.io" self.assertFalse(self.get_snitch_map_for(THIRD_PARTY_BASE)) self.load_url(("https://privacybadger-tests.{}/html/" "localstorage.html").format(FIRST_PARTY_BASE)) # TODO We get some intermittent failures for this test. # It seems we sometimes miss the setting of localStorage items # because the script runs after we already checked what's in localStorage. # We can work around this race condition by reloading the page. self.driver.refresh() self.assertEqual( pbtest.retry_until(partial(self.get_snitch_map_for, THIRD_PARTY_BASE), times=3), [FIRST_PARTY_BASE])
def test_async_tracking_misattribution_bug(self): self.load_url("https://www.eff.org/files/badger_test_fixtures/" "async_localstorage_attribution_bug.html") # the above HTML page reloads itself furiously to trigger our bug # we need to wait for it to finish reloading self.wait_for_script("return window.DONE_RELOADING === true") # the HTML page contains: # an iframe from gistcdn.githack.com that writes to localStorage self.assertEqual( pbtest.retry_until(partial(self.get_snitch_map_for, "githack.com")), ["eff.org"], msg="IFrame sets localStorage but was not flagged as a tracker.") # and an image from raw.githubusercontent.com that doesn't do any tracking self.assertFalse(self.get_snitch_map_for("raw.githubusercontent.com"), msg="Image is not a tracker but was flagged as one.")
def test_async_tracking_misattribution_bug(self): self.load_url( "https://gitcdn.link/cdn/ghostwords/" "d3685dc39f7e67dddf1edf2614beb6fc/raw/f52060b329dfeb4e264fcd21c48206cff98786f6/" "privacy_badger_async_bug_test_fixture.html") # the above HTML page reloads itself furiously to trigger our bug # we need to wait for it to finish reloading self.wait_for_script("return window.DONE_RELOADING === true") # the HTML page contains: # an iframe from gistcdn.githack.com that writes to localStorage self.assertEqual( pbtest.retry_until(partial(self.get_snitch_map_for, "githack.com")), ["gitcdn.link"], msg="IFrame sets localStorage but was not flagged as a tracker.") # and an image from raw.githubusercontent.com that doesn't do any tracking self.assertFalse(self.get_snitch_map_for("raw.githubusercontent.com"), msg="Image is not a tracker but was flagged as one.")
def test_no_unwrapping_when_disabled(self): """Tests that Google search result links still match our selectors.""" # use the browser-appropriate selector SELECTOR = "a[ping]" if pbtest.shim.browser_type == "firefox": SELECTOR = "a[onmousedown^='return rwt(this,']" # turn off link unwrapping on Google # so that we can test our selectors self.disable_badger_on_site(self.GOOGLE_SEARCH_DOMAIN) def _perform_search_and_check_results(): self.perform_google_search() search_results = self.driver.find_elements_by_css_selector( SELECTOR) # remove "About this result" links as they do not get cleaned # (they don't match any of the `trap_link` selectors) # and so they fail the rel check below search_results = [ a for a in search_results if (a.text or a.get_attribute('textContent') != self.SEARCH_RESULT_URL or a.get_attribute('innerHTML') != self.SEARCH_RESULT_URL) ] # check the results hrefs = [link.get_attribute('href') for link in search_results] self.assertIn(self.SEARCH_RESULT_URL, hrefs, "At least one search result points to our homepage") return True self.assertTrue( pbtest.retry_until( pbtest.convert_exceptions_to_false( _perform_search_and_check_results)), "Search results still fail our checks after several attempts")
def test_async_tracking_misattribution_bug(self): self.load_url( "https://gitcdn.link/cdn/ghostwords/" "d3685dc39f7e67dddf1edf2614beb6fc/raw/f52060b329dfeb4e264fcd21c48206cff98786f6/" "privacy_badger_async_bug_test_fixture.html" ) # the above HTML page reloads itself furiously to trigger our bug # we need to wait for it to finish reloading self.wait_for_script("return window.DONE_RELOADING === true") # the HTML page contains: # an iframe from gistcdn.githack.com that writes to localStorage self.assertEqual( pbtest.retry_until(partial(self.get_snitch_map_for, "githack.com")), ["gitcdn.link"], msg="IFrame sets localStorage but was not flagged as a tracker.") # and an image from raw.githubusercontent.com that doesn't do any tracking self.assertFalse(self.get_snitch_map_for("raw.githubusercontent.com"), msg="Image is not a tracker but was flagged as one.")
def test_async_tracking_misattribution_bug(self): self.load_url( "https://cdn.rawgit.com/ghostwords" "/d3685dc39f7e67dddf1edf2614beb6fc/raw/a78cfd6c86d51a8d8ab1e214e4e49e2c025d4715" "/privacy_badger_async_bug_test_fixture.html" ) # the above HTML page reloads itself furiously to trigger our bug # we need to wait for it to finish reloading self.wait_for_script("return window.DONE_RELOADING === true") tracking_detected = pbtest.retry_until( partial(self.detected_tracking_by, "githack.com")) # the HTML page contains: # an iframe from gistcdn.githack.com that writes to localStorage self.assertTrue(tracking_detected, msg="IFrame sets localStorage but was not flagged as a tracker.") # and an image from raw.githubusercontent.com that doesn't do any tracking self.assertFalse(self.detected_tracking_by("raw.githubusercontent.com"), msg="Image is not a tracker but was flagged as one.")
def test_async_tracking_attribution_bug(self): FIRST_PARTY_BASE = "eff.org" THIRD_PARTY_BASE = "efforg.github.io" self.load_url((f"https://privacybadger-tests.{FIRST_PARTY_BASE}/html/" "async_localstorage_attribution_bug.html")) # the above HTML page reloads itself furiously to trigger our bug # we need to wait for it to finish reloading self.wait_for_script("return window.DONE_RELOADING === true") # the HTML page contains: # an iframe from THIRD_PARTY_BASE that writes to localStorage self.assertEqual( [FIRST_PARTY_BASE], pbtest.retry_until( partial(self.get_snitch_map_for, THIRD_PARTY_BASE)), msg="Frame sets localStorage but was not flagged as a tracker.") # and an image from raw.githubusercontent.com that doesn't do any tracking self.assertFalse(self.get_snitch_map_for("raw.githubusercontent.com"), msg="Image is not a tracker but was flagged as one.")
def test_ga_js_surrogate(self): # verify the surrogate is present self.load_url(self.options_url) self.assertTrue(self.js( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "return sdb.hostnames.hasOwnProperty('www.google-analytics.com');" ), "Surrogate is missing but should be present.") # verify site loads self.assertTrue( self.load_ga_js_test_page(), "Page failed to load even before we did anything." ) # block ga.js (known to break the site) self.load_url(self.options_url) # also back up the surrogate definition before removing it ga_backup = self.js( "let bg = chrome.extension.getBackgroundPage();" "bg.badger.heuristicBlocking.blacklistOrigin('www.google-analytics.com', 'google-analytics.com');" "const sdb = bg.require('surrogatedb');" "return JSON.stringify(sdb.hostnames['www.google-analytics.com']);" ) # now remove the surrogate self.js( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "delete sdb.hostnames['www.google-analytics.com'];" ) # wait until this happens self.wait_for_script( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "return !sdb.hostnames.hasOwnProperty('www.google-analytics.com');", timeout=5, message="Timed out waiting for surrogate to get removed." ) # verify site breaks self.assertFalse( self.load_ga_js_test_page(), "Page loaded successfully when it should have failed." ) # re-enable surrogate self.load_url(self.options_url) self.js( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "sdb.hostnames['www.google-analytics.com'] = JSON.parse('%s');" % ga_backup ) # wait until this happens self.wait_for_script( "let bg = chrome.extension.getBackgroundPage();" "const sdb = bg.require('surrogatedb');" "return sdb.hostnames.hasOwnProperty('www.google-analytics.com');", timeout=5, message="Timed out waiting for surrogate to get readded." ) # verify site loads again self.assertTrue( retry_until(self.load_ga_js_test_page), "Page failed to load after surrogation." )
def test_ga_js_surrogate(self): # open the background page self.load_url(self.bg_url) # verify the surrogate is present self.assertTrue( self. js("const sdb = require('surrogatedb');" "return sdb.hostnames.hasOwnProperty('www.google-analytics.com');" ), "Surrogate is missing but should be present.") # verify site loads self.assertTrue(self.load_ga_js_test_page(), "Page failed to load even before we did anything.") # block ga.js (known to break the site) self.load_url(self.bg_url) # also back up the surrogate definition before removing it ga_backup = self.js( "badger.heuristicBlocking.blacklistOrigin('www.google-analytics.com', 'google-analytics.com');" "const sdb = require('surrogatedb');" "return JSON.stringify(sdb.hostnames['www.google-analytics.com']);" ) # now remove the surrogate self.js("const sdb = require('surrogatedb');" "delete sdb.hostnames['www.google-analytics.com'];") # wait until this happens self.wait_for_script( "const sdb = require('surrogatedb');" "return !sdb.hostnames.hasOwnProperty('www.google-analytics.com');", timeout=5, message="Timed out waiting for surrogate to get removed.") # need to keep PB's background page open for our changes to persist ... # so, open and switch to a new window self.open_window() # verify site breaks self.assertFalse( self.load_ga_js_test_page(), "Page loaded successfully when it should have failed.") # switch back to PB's background page switch_to_window_with_url(self.driver, self.bg_url) # re-enable surrogate self.js( "const sdb = require('surrogatedb');" "sdb.hostnames['www.google-analytics.com'] = JSON.parse('%s');" % ga_backup) # wait until this happens self.wait_for_script( "const sdb = require('surrogatedb');" "return sdb.hostnames.hasOwnProperty('www.google-analytics.com');", timeout=5, message="Timed out waiting for surrogate to get readded.") # still need to keep PB's bg page open ... self.open_window() # verify site loads again self.assertTrue(retry_until(self.load_ga_js_test_page), "Page failed to load after surrogation.")