예제 #1
0
 def _check_calls(
     self,
     db,
     symbol_prefix,
     doc_url,
     top_url,
     expected_method_calls,
     expected_gets_and_sets,
 ):
     """Helper to check method calls and accesses in each frame"""
     rows = db_utils.get_javascript_entries(db, all_columns=True)
     observed_gets_and_sets = set()
     observed_calls = set()
     for row in rows:
         if not row["symbol"].startswith(symbol_prefix):
             continue
         symbol = re.sub(symbol_prefix, "", row["symbol"])
         assert row["document_url"] == doc_url
         assert row["top_level_url"] == top_url
         if row["operation"] == "get" or row["operation"] == "set":
             observed_gets_and_sets.add(
                 (symbol, row["operation"], row["value"]))
         else:
             observed_calls.add(
                 (symbol, row["operation"], row["arguments"]))
     assert observed_calls == expected_method_calls
     assert observed_gets_and_sets == expected_gets_and_sets
예제 #2
0
 def test_audio_fingerprinting(self):
     db = self.visit("/audio_fingerprinting.html")
     # Check that all calls and methods are recorded
     rows = db_utils.get_javascript_entries(db)
     observed_symbols = set()
     for item in rows:
         observed_symbols.add(item[1])
     assert AUDIO_SYMBOLS == observed_symbols
예제 #3
0
 def test_js_time_stamp(self):
     # Check that timestamp is recorded correctly for the javascript table
     MAX_TIMEDELTA = 60  # max time diff in seconds
     db = self.visit("/js_call_stack.html")
     utc_now = datetime.utcnow()  # OpenWPM stores timestamp in UTC time
     rows = db_utils.get_javascript_entries(db, all_columns=True)
     assert len(rows)  # make sure we have some JS events captured
     for row in rows:
         js_time = datetime.strptime(row["time_stamp"],
                                     "%Y-%m-%dT%H:%M:%S.%fZ")
         # compare UTC now and the timestamp recorded at the visit
         assert (utc_now - js_time).seconds < MAX_TIMEDELTA
     assert not db_utils.any_command_failed(db)
예제 #4
0
 def test_canvas_fingerprinting(self):
     db = self.visit("/canvas_fingerprinting.html")
     # Check that all calls and methods are recorded
     rows = db_utils.get_javascript_entries(db)
     observed_rows = set()
     for row in rows:
         item = (
             row["script_url"],
             row["symbol"],
             row["operation"],
             row["value"],
             row["arguments"],
         )
         observed_rows.add(item)
     assert CANVAS_CALLS == observed_rows
예제 #5
0
 def test_document_cookie_instrumentation(self):
     db = self.visit(utilities.BASE_TEST_URL + "/js_cookie.html")
     rows = db_utils.get_javascript_entries(db, all_columns=True)
     captured_cookie_calls = set()
     for row in rows:
         item = (
             row["script_url"],
             row["script_line"],
             row["script_col"],
             row["func_name"],
             row["script_loc_eval"],
             row["call_stack"],
             row["symbol"],
             row["operation"],
             row["value"],
         )
         captured_cookie_calls.add(item)
     assert captured_cookie_calls == DOCUMENT_COOKIE_READ_WRITE
예제 #6
0
 def test_js_call_stack(self):
     db = self.visit("/js_call_stack.html")
     # Check that all stack info are recorded
     rows = db_utils.get_javascript_entries(db, all_columns=True)
     observed_rows = set()
     for row in rows:
         item = (
             row["script_url"],
             row["script_line"],
             row["script_col"],
             row["func_name"],
             row["script_loc_eval"],
             row["call_stack"],
             row["symbol"],
             row["operation"],
         )
         observed_rows.add(item)
     assert JS_STACK_CALLS == observed_rows
예제 #7
0
 def test_webrtc_localip(self):
     db = self.visit("/webrtc_localip.html")
     # Check that all calls and methods are recorded
     rows = db_utils.get_javascript_entries(db)
     observed_rows = set()
     for row in rows:
         if row["symbol"] == "RTCPeerConnection.setLocalDescription" and (
                 row["operation"] == "call"):
             sdp_offer = row["arguments"]
             self.check_webrtc_sdp_offer(sdp_offer)
         else:
             item = (
                 row["script_url"],
                 row["symbol"],
                 row["operation"],
                 row["value"],
                 row["arguments"],
             )
             observed_rows.add(item)
     assert WEBRTC_CALLS == observed_rows
예제 #8
0
    def test_instrument_object(self):
        """Ensure instrumentObject logs all property gets, sets, and calls"""
        db = self.visit("/js_instrument/instrument_object.html")
        self._check_calls(
            db=db,
            symbol_prefix="window.test.",
            doc_url=self.TOP_URL,
            top_url=self.TOP_URL,
            expected_method_calls=self.METHOD_CALLS,
            expected_gets_and_sets=self.GETS_AND_SETS,
        )
        self._check_calls(
            db=db,
            symbol_prefix="window.frame1Test.",
            doc_url=self.FRAME1_URL,
            top_url=self.TOP_URL,
            expected_method_calls=self.METHOD_CALLS,
            expected_gets_and_sets=self.GETS_AND_SETS,
        )
        self._check_calls(
            db=db,
            symbol_prefix="window.frame2Test.",
            doc_url=self.FRAME2_URL,
            top_url=self.TOP_URL,
            expected_method_calls=self.METHOD_CALLS,
            expected_gets_and_sets=self.GETS_AND_SETS,
        )

        # Check calls of recursive instrumentation
        observed_gets_and_sets = set()
        observed_calls = set()
        rows = db_utils.get_javascript_entries(db, all_columns=True)
        for row in rows:
            if not row["symbol"].startswith("window.test2.nestedObj"):
                continue
            assert row["document_url"] == self.TOP_URL
            assert row["top_level_url"] == self.TOP_URL
            if row["operation"] == "get" or row["operation"] == "set":
                observed_gets_and_sets.add(
                    (row["symbol"], row["operation"], row["value"]))
            else:
                observed_calls.add(
                    (row["symbol"], row["operation"], row["arguments"]))
        assert observed_calls == self.RECURSIVE_METHOD_CALLS
        assert observed_gets_and_sets == self.RECURSIVE_GETS_AND_SETS

        # Check that calls not present after default recursion limit (5)
        # We should only see the window.test2.l1.l2.l3.l4.l5.prop access
        # and not window.test2.l1.l2.l3.l4.l5.l6.prop access.
        prop_access = set()
        for row in rows:
            if not row["symbol"].startswith("window.test2.l1"):
                continue
            assert row["document_url"] == self.TOP_URL
            assert row["top_level_url"] == self.TOP_URL
            prop_access.add((row["symbol"], row["operation"], row["value"]))
        assert prop_access == self.RECURSIVE_PROP_SET

        # Check calls of object with sets prevented
        observed_gets_and_sets = set()
        observed_calls = set()
        for row in rows:
            if not row["symbol"].startswith("window.test3"):
                continue
            assert row["document_url"] == self.TOP_URL
            assert row["top_level_url"] == self.TOP_URL
            if row["operation"] == "call":
                observed_calls.add(
                    (row["symbol"], row["operation"], row["arguments"]))
            else:
                observed_gets_and_sets.add(
                    (row["symbol"], row["operation"], row["value"]))
        assert observed_calls == self.SET_PREVENT_CALLS
        assert observed_gets_and_sets == self.SET_PREVENT_GETS_AND_SETS