2018-07-21 11:04:18 +03:00
|
|
|
import os
|
2017-10-10 21:35:13 +03:00
|
|
|
from datetime import datetime
|
2021-02-22 19:51:32 +03:00
|
|
|
from pathlib import Path
|
|
|
|
from sqlite3 import Row
|
|
|
|
from typing import List, Tuple
|
2018-07-21 11:04:18 +03:00
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
import pytest
|
2017-10-10 21:35:13 +03:00
|
|
|
|
2021-02-22 19:51:32 +03:00
|
|
|
from openwpm.config import BrowserParams, ManagerParams
|
2020-11-19 16:24:06 +03:00
|
|
|
from openwpm.utilities import db_utils
|
|
|
|
|
2019-04-26 20:07:40 +03:00
|
|
|
from . import utilities
|
2018-07-21 11:04:18 +03:00
|
|
|
from .openwpmtest import OpenWPMTest
|
2017-01-05 02:50:29 +03:00
|
|
|
|
|
|
|
# Expected Navigator and Screen properties
|
|
|
|
PROPERTIES = {
|
|
|
|
"window.navigator.appCodeName",
|
|
|
|
"window.navigator.appName",
|
|
|
|
"window.navigator.appVersion",
|
|
|
|
"window.navigator.buildID",
|
|
|
|
"window.navigator.cookieEnabled",
|
|
|
|
"window.navigator.doNotTrack",
|
|
|
|
"window.navigator.geolocation",
|
|
|
|
"window.navigator.language",
|
|
|
|
"window.navigator.languages",
|
|
|
|
"window.navigator.onLine",
|
|
|
|
"window.navigator.oscpu",
|
|
|
|
"window.navigator.platform",
|
|
|
|
"window.navigator.product",
|
|
|
|
"window.navigator.productSub",
|
|
|
|
"window.navigator.userAgent",
|
|
|
|
"window.navigator.vendorSub",
|
|
|
|
"window.navigator.vendor",
|
|
|
|
"window.screen.pixelDepth",
|
2020-09-11 16:14:09 +03:00
|
|
|
"window.screen.colorDepth",
|
2017-01-05 02:50:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
# Canvas Fingerprinting DB calls and property sets
|
|
|
|
CANVAS_TEST_URL = u"%s/canvas_fingerprinting.html" % utilities.BASE_TEST_URL
|
|
|
|
|
|
|
|
CANVAS_CALLS = {
|
2020-09-11 16:14:09 +03:00
|
|
|
(CANVAS_TEST_URL, u"CanvasRenderingContext2D.fillStyle", u"set", u"#f60", None),
|
|
|
|
(
|
|
|
|
CANVAS_TEST_URL,
|
|
|
|
u"CanvasRenderingContext2D.textBaseline",
|
|
|
|
u"set",
|
|
|
|
u"alphabetic",
|
|
|
|
None,
|
|
|
|
),
|
|
|
|
(CANVAS_TEST_URL, u"CanvasRenderingContext2D.textBaseline", u"set", u"top", None),
|
|
|
|
(CANVAS_TEST_URL, u"CanvasRenderingContext2D.font", u"set", u"14px 'Arial'", None),
|
|
|
|
(CANVAS_TEST_URL, u"CanvasRenderingContext2D.fillStyle", u"set", u"#069", None),
|
|
|
|
(
|
|
|
|
CANVAS_TEST_URL,
|
|
|
|
u"CanvasRenderingContext2D.fillStyle",
|
|
|
|
u"set",
|
|
|
|
u"rgba(102, 204, 0, 0.7)",
|
|
|
|
None,
|
|
|
|
),
|
|
|
|
(CANVAS_TEST_URL, u"HTMLCanvasElement.getContext", u"call", u"", u'["2d"]'),
|
|
|
|
(
|
|
|
|
CANVAS_TEST_URL,
|
|
|
|
u"CanvasRenderingContext2D.fillRect",
|
|
|
|
u"call",
|
|
|
|
u"",
|
|
|
|
u"[125,1,62,20]",
|
|
|
|
),
|
|
|
|
(CANVAS_TEST_URL, u"HTMLCanvasElement.toDataURL", u"call", u"", None),
|
|
|
|
(
|
|
|
|
CANVAS_TEST_URL,
|
|
|
|
u"CanvasRenderingContext2D.fillText",
|
|
|
|
u"call",
|
|
|
|
u"",
|
|
|
|
u'["BrowserLeaks,com <canvas> 1.0",4,17]',
|
|
|
|
),
|
|
|
|
(
|
|
|
|
CANVAS_TEST_URL,
|
|
|
|
u"CanvasRenderingContext2D.fillText",
|
|
|
|
u"call",
|
|
|
|
u"",
|
|
|
|
u'["BrowserLeaks,com <canvas> 1.0",2,15]',
|
|
|
|
),
|
2017-01-05 02:50:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
WEBRTC_TEST_URL = u"%s/webrtc_localip.html" % utilities.BASE_TEST_URL
|
|
|
|
|
|
|
|
WEBRTC_CALLS = {
|
2020-09-11 16:14:09 +03:00
|
|
|
(
|
|
|
|
WEBRTC_TEST_URL,
|
|
|
|
u"RTCPeerConnection.createOffer",
|
|
|
|
u"call",
|
|
|
|
u"",
|
|
|
|
u'["FUNCTION","FUNCTION"]',
|
|
|
|
),
|
|
|
|
(WEBRTC_TEST_URL, u"RTCPeerConnection.createDataChannel", u"call", u"", u'[""]'),
|
|
|
|
(
|
|
|
|
WEBRTC_TEST_URL,
|
|
|
|
u"RTCPeerConnection.createDataChannel",
|
|
|
|
u"call",
|
|
|
|
u"",
|
|
|
|
u'["","{\\"reliable\\":false}"]',
|
|
|
|
),
|
|
|
|
(WEBRTC_TEST_URL, u"RTCPeerConnection.onicecandidate", u"set", u"FUNCTION", None),
|
2017-01-05 02:50:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
# we expect these strings to be present in the WebRTC SDP
|
2020-09-11 16:14:09 +03:00
|
|
|
WEBRTC_SDP_OFFER_STRINGS = (
|
|
|
|
"a=ice-options",
|
|
|
|
"o=mozilla...THIS_IS_SDPARTA",
|
|
|
|
"IN IP4",
|
|
|
|
"a=fingerprint:sha-256",
|
|
|
|
"a=ice-options:",
|
|
|
|
"a=msid-semantic",
|
|
|
|
"m=application",
|
|
|
|
"a=sendrecv",
|
|
|
|
"a=ice-pwd:",
|
|
|
|
"a=ice-ufrag:",
|
|
|
|
"a=mid:0",
|
|
|
|
"a=sctp-port:",
|
|
|
|
"a=setup:",
|
|
|
|
)
|
2017-01-05 02:50:29 +03:00
|
|
|
|
|
|
|
# AudioContext and AudioNode symbols we expect from our test script
|
|
|
|
AUDIO_SYMBOLS = {
|
|
|
|
u"AudioContext.createOscillator",
|
|
|
|
u"AudioContext.createAnalyser",
|
|
|
|
u"AudioContext.createGain",
|
|
|
|
u"AudioContext.createScriptProcessor",
|
|
|
|
u"GainNode.gain",
|
|
|
|
u"OscillatorNode.type",
|
|
|
|
u"OscillatorNode.connect",
|
|
|
|
u"AnalyserNode.connect",
|
|
|
|
u"ScriptProcessorNode.connect",
|
|
|
|
u"AudioContext.destination",
|
|
|
|
u"GainNode.connect",
|
|
|
|
u"ScriptProcessorNode.onaudioprocess",
|
|
|
|
u"OscillatorNode.start",
|
|
|
|
u"AnalyserNode.frequencyBinCount",
|
|
|
|
u"AnalyserNode.getFloatFrequencyData",
|
|
|
|
u"AnalyserNode.disconnect",
|
|
|
|
u"ScriptProcessorNode.disconnect",
|
|
|
|
u"GainNode.disconnect",
|
2020-09-11 16:14:09 +03:00
|
|
|
u"OscillatorNode.stop",
|
2017-01-05 02:50:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
JS_STACK_TEST_URL = u"%s/js_call_stack.html" % utilities.BASE_TEST_URL
|
|
|
|
JS_STACK_TEST_SCRIPT_URL = u"%s/stack.js" % utilities.BASE_TEST_URL
|
|
|
|
|
|
|
|
JS_STACK_CALLS = {
|
2020-09-11 16:14:09 +03:00
|
|
|
(
|
|
|
|
JS_STACK_TEST_URL,
|
|
|
|
u"1",
|
|
|
|
u"1",
|
|
|
|
u"",
|
|
|
|
u"line 10 > eval",
|
|
|
|
u"",
|
|
|
|
u"window.navigator.appName",
|
|
|
|
u"get",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
JS_STACK_TEST_SCRIPT_URL,
|
|
|
|
u"3",
|
|
|
|
u"5",
|
|
|
|
u"js_check_navigator",
|
|
|
|
u"",
|
|
|
|
u"",
|
|
|
|
u"window.navigator.userAgent",
|
|
|
|
u"get",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
JS_STACK_TEST_SCRIPT_URL,
|
|
|
|
u"1",
|
|
|
|
u"1",
|
|
|
|
u"",
|
|
|
|
u"line 4 > eval",
|
|
|
|
u"",
|
|
|
|
u"window.navigator.platform",
|
|
|
|
u"get",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
JS_STACK_TEST_SCRIPT_URL,
|
|
|
|
u"1",
|
|
|
|
u"1",
|
|
|
|
u"",
|
|
|
|
u"line 11 > eval",
|
|
|
|
u"",
|
|
|
|
u"window.navigator.buildID",
|
|
|
|
u"get",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
JS_STACK_TEST_SCRIPT_URL,
|
|
|
|
u"3",
|
|
|
|
u"1",
|
|
|
|
u"anonymous",
|
|
|
|
u"line 14 > Function",
|
|
|
|
u"",
|
|
|
|
u"window.navigator.appVersion",
|
|
|
|
u"get",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
JS_STACK_TEST_URL,
|
|
|
|
u"7",
|
|
|
|
u"9",
|
|
|
|
u"check_navigator",
|
|
|
|
u"",
|
|
|
|
u"",
|
|
|
|
u"window.navigator.userAgent",
|
|
|
|
u"get",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
JS_STACK_TEST_URL,
|
|
|
|
u"1",
|
|
|
|
u"1",
|
|
|
|
u"",
|
|
|
|
u"line 8 > eval",
|
|
|
|
u"",
|
|
|
|
u"window.navigator.appCodeName",
|
|
|
|
u"get",
|
|
|
|
),
|
2017-01-05 02:50:29 +03:00
|
|
|
}
|
|
|
|
|
2020-09-11 16:14:09 +03:00
|
|
|
JS_COOKIE_TEST_URL = u"%s/js_cookie.html" % utilities.BASE_TEST_URL
|
2017-01-05 02:50:29 +03:00
|
|
|
|
|
|
|
DOCUMENT_COOKIE_READ = (
|
|
|
|
JS_COOKIE_TEST_URL,
|
2020-09-11 16:14:09 +03:00
|
|
|
u"8",
|
|
|
|
u"9",
|
|
|
|
u"set_cookie",
|
|
|
|
u"",
|
|
|
|
u"set_cookie@" + JS_COOKIE_TEST_URL + ":8:9"
|
|
|
|
"\nonload@" + JS_COOKIE_TEST_URL + ":1:1",
|
|
|
|
u"window.document.cookie",
|
|
|
|
u"get",
|
|
|
|
u"test_cookie=Test-0123456789",
|
|
|
|
)
|
2017-01-05 02:50:29 +03:00
|
|
|
|
|
|
|
DOCUMENT_COOKIE_WRITE = (
|
|
|
|
JS_COOKIE_TEST_URL,
|
2020-09-11 16:14:09 +03:00
|
|
|
u"7",
|
|
|
|
u"9",
|
|
|
|
u"set_cookie",
|
|
|
|
u"",
|
|
|
|
u"set_cookie@" + JS_COOKIE_TEST_URL + ":7:9"
|
|
|
|
"\nonload@" + JS_COOKIE_TEST_URL + ":1:1",
|
|
|
|
u"window.document.cookie",
|
|
|
|
u"set",
|
|
|
|
u"test_cookie=Test-0123456789; " "expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/",
|
|
|
|
)
|
2017-01-05 02:50:29 +03:00
|
|
|
|
2021-02-22 19:51:32 +03:00
|
|
|
DOCUMENT_COOKIE_READ_WRITE = {DOCUMENT_COOKIE_READ, DOCUMENT_COOKIE_WRITE}
|
2015-12-22 00:21:15 +03:00
|
|
|
|
|
|
|
|
2016-04-12 03:47:05 +03:00
|
|
|
class TestExtension(OpenWPMTest):
|
2021-02-22 19:51:32 +03:00
|
|
|
def get_config(
|
|
|
|
self, data_dir: Path = None
|
|
|
|
) -> Tuple[ManagerParams, List[BrowserParams]]:
|
2016-12-18 20:42:45 +03:00
|
|
|
manager_params, browser_params = self.get_test_config(data_dir)
|
2020-12-02 12:10:45 +03:00
|
|
|
browser_params[0].js_instrument = True
|
2015-12-22 00:21:15 +03:00
|
|
|
return manager_params, browser_params
|
|
|
|
|
2021-02-22 19:51:32 +03:00
|
|
|
def test_property_enumeration(self) -> None:
|
2020-09-11 16:14:09 +03:00
|
|
|
test_url = utilities.BASE_TEST_URL + "/property_enumeration.html"
|
2016-12-18 20:42:45 +03:00
|
|
|
db = self.visit(test_url)
|
2020-09-11 16:14:09 +03:00
|
|
|
rows = db_utils.query_db(db, "SELECT script_url, symbol FROM javascript")
|
2015-12-22 00:21:15 +03:00
|
|
|
observed_symbols = set()
|
2016-04-12 03:47:05 +03:00
|
|
|
for script_url, symbol in rows:
|
|
|
|
assert script_url == test_url
|
2015-12-22 00:21:15 +03:00
|
|
|
observed_symbols.add(symbol)
|
2017-01-05 02:50:29 +03:00
|
|
|
assert PROPERTIES == observed_symbols
|
2015-12-30 00:43:17 +03:00
|
|
|
|
2021-02-22 19:51:32 +03:00
|
|
|
def test_canvas_fingerprinting(self) -> None:
|
2020-09-11 16:14:09 +03:00
|
|
|
db = self.visit("/canvas_fingerprinting.html")
|
2015-12-30 00:43:17 +03:00
|
|
|
# Check that all calls and methods are recorded
|
2016-12-30 23:33:07 +03:00
|
|
|
rows = db_utils.get_javascript_entries(db)
|
2015-12-30 00:43:17 +03:00
|
|
|
observed_rows = set()
|
2017-10-10 21:35:13 +03:00
|
|
|
for row in rows:
|
2021-02-22 19:51:32 +03:00
|
|
|
assert isinstance(row, Row)
|
2020-09-11 16:14:09 +03:00
|
|
|
item = (
|
|
|
|
row["script_url"],
|
|
|
|
row["symbol"],
|
|
|
|
row["operation"],
|
|
|
|
row["value"],
|
|
|
|
row["arguments"],
|
|
|
|
)
|
2015-12-30 00:43:17 +03:00
|
|
|
observed_rows.add(item)
|
2017-01-05 02:50:29 +03:00
|
|
|
assert CANVAS_CALLS == observed_rows
|
2016-04-12 03:47:05 +03:00
|
|
|
|
2021-02-22 19:51:32 +03:00
|
|
|
def test_extension_gets_correct_visit_id(self) -> None:
|
2020-09-11 16:14:09 +03:00
|
|
|
url_a = utilities.BASE_TEST_URL + "/simple_a.html"
|
|
|
|
url_b = utilities.BASE_TEST_URL + "/simple_b.html"
|
2021-02-22 19:51:32 +03:00
|
|
|
self.visit(url_a)
|
|
|
|
db = self.visit(url_b)
|
2016-05-05 18:38:56 +03:00
|
|
|
|
2021-02-22 19:51:32 +03:00
|
|
|
qry_res = db_utils.query_db(db, "SELECT visit_id, site_url FROM site_visits")
|
2016-05-05 18:38:56 +03:00
|
|
|
|
|
|
|
# Construct dict mapping site_url to visit_id
|
|
|
|
visit_ids = dict()
|
|
|
|
for row in qry_res:
|
|
|
|
visit_ids[row[1]] = row[0]
|
|
|
|
|
2016-12-30 23:33:07 +03:00
|
|
|
simple_a_visit_id = db_utils.query_db(
|
2021-02-22 19:51:32 +03:00
|
|
|
db,
|
|
|
|
"SELECT visit_id FROM javascript WHERE symbol=?",
|
2020-09-11 16:14:09 +03:00
|
|
|
("window.navigator.userAgent",),
|
2017-01-05 02:50:29 +03:00
|
|
|
)
|
2016-05-05 18:38:56 +03:00
|
|
|
|
2016-12-30 23:33:07 +03:00
|
|
|
simple_b_visit_id = db_utils.query_db(
|
2021-02-22 19:51:32 +03:00
|
|
|
db,
|
|
|
|
"SELECT visit_id FROM javascript WHERE symbol=?",
|
2020-09-11 16:14:09 +03:00
|
|
|
("window.navigator.platform",),
|
2017-01-05 02:50:29 +03:00
|
|
|
)
|
2016-05-05 18:38:56 +03:00
|
|
|
|
|
|
|
assert visit_ids[url_a] == simple_a_visit_id[0][0]
|
|
|
|
assert visit_ids[url_b] == simple_b_visit_id[0][0]
|
|
|
|
|
2021-02-22 19:51:32 +03:00
|
|
|
def check_webrtc_sdp_offer(self, sdp_str: str) -> None:
|
2016-04-12 03:47:05 +03:00
|
|
|
"""Make sure the SDP offer includes expected fields/strings.
|
|
|
|
|
|
|
|
SDP offer contains randomly generated strings (e.g. GUID). That's why
|
|
|
|
we don't expect a fixed string but only check the presence of certain
|
|
|
|
protocol fields.
|
|
|
|
"""
|
2017-01-05 02:50:29 +03:00
|
|
|
for expected_str in WEBRTC_SDP_OFFER_STRINGS:
|
2016-04-12 03:47:05 +03:00
|
|
|
assert expected_str in sdp_str
|
|
|
|
|
2021-02-22 19:51:32 +03:00
|
|
|
def test_webrtc_localip(self) -> None:
|
2020-09-11 16:14:09 +03:00
|
|
|
db = self.visit("/webrtc_localip.html")
|
2016-04-12 03:47:05 +03:00
|
|
|
# Check that all calls and methods are recorded
|
2016-12-30 23:33:07 +03:00
|
|
|
rows = db_utils.get_javascript_entries(db)
|
2016-04-12 03:47:05 +03:00
|
|
|
observed_rows = set()
|
2017-10-10 21:35:13 +03:00
|
|
|
for row in rows:
|
2021-02-22 19:51:32 +03:00
|
|
|
assert isinstance(row, Row)
|
2020-09-11 16:14:09 +03:00
|
|
|
if row["symbol"] == "RTCPeerConnection.setLocalDescription" and (
|
|
|
|
row["operation"] == "call"
|
|
|
|
):
|
|
|
|
sdp_offer = row["arguments"]
|
2016-04-12 03:47:05 +03:00
|
|
|
self.check_webrtc_sdp_offer(sdp_offer)
|
|
|
|
else:
|
2020-09-11 16:14:09 +03:00
|
|
|
item = (
|
|
|
|
row["script_url"],
|
|
|
|
row["symbol"],
|
|
|
|
row["operation"],
|
|
|
|
row["value"],
|
|
|
|
row["arguments"],
|
|
|
|
)
|
2016-04-12 03:47:05 +03:00
|
|
|
observed_rows.add(item)
|
2017-01-05 02:50:29 +03:00
|
|
|
assert WEBRTC_CALLS == observed_rows
|
2016-09-12 18:18:22 +03:00
|
|
|
|
2017-01-05 02:50:29 +03:00
|
|
|
@pytest.mark.skipif(
|
2021-01-29 14:21:36 +03:00
|
|
|
"CI" in os.environ and os.environ["CI"] == "true",
|
|
|
|
reason="Flaky on CI",
|
2020-09-11 16:14:09 +03:00
|
|
|
)
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_audio_fingerprinting(self):
|
2020-09-11 16:14:09 +03:00
|
|
|
db = self.visit("/audio_fingerprinting.html")
|
2016-09-12 18:18:22 +03:00
|
|
|
# Check that all calls and methods are recorded
|
2016-12-30 23:33:07 +03:00
|
|
|
rows = db_utils.get_javascript_entries(db)
|
2016-09-12 18:18:22 +03:00
|
|
|
observed_symbols = set()
|
|
|
|
for item in rows:
|
|
|
|
observed_symbols.add(item[1])
|
2017-01-05 02:50:29 +03:00
|
|
|
assert AUDIO_SYMBOLS == observed_symbols
|
2016-09-12 18:18:22 +03:00
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_js_call_stack(self):
|
2020-09-11 16:14:09 +03:00
|
|
|
db = self.visit("/js_call_stack.html")
|
2016-12-01 02:04:43 +03:00
|
|
|
# Check that all stack info are recorded
|
2016-12-30 23:33:07 +03:00
|
|
|
rows = db_utils.get_javascript_entries(db, all_columns=True)
|
2016-12-01 02:04:43 +03:00
|
|
|
observed_rows = set()
|
2017-10-10 21:35:13 +03:00
|
|
|
for row in rows:
|
2020-09-11 16:14:09 +03:00
|
|
|
item = (
|
|
|
|
row["script_url"],
|
|
|
|
row["script_line"],
|
|
|
|
row["script_col"],
|
|
|
|
row["func_name"],
|
|
|
|
row["script_loc_eval"],
|
|
|
|
row["call_stack"],
|
|
|
|
row["symbol"],
|
|
|
|
row["operation"],
|
|
|
|
)
|
2017-10-10 21:35:13 +03:00
|
|
|
observed_rows.add(item)
|
2017-01-05 02:50:29 +03:00
|
|
|
assert JS_STACK_CALLS == observed_rows
|
2016-12-01 02:04:43 +03:00
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_js_time_stamp(self):
|
2016-12-15 02:03:25 +03:00
|
|
|
# Check that timestamp is recorded correctly for the javascript table
|
2020-03-12 13:13:36 +03:00
|
|
|
MAX_TIMEDELTA = 60 # max time diff in seconds
|
2020-09-11 16:14:09 +03:00
|
|
|
db = self.visit("/js_call_stack.html")
|
2016-12-15 02:03:25 +03:00
|
|
|
utc_now = datetime.utcnow() # OpenWPM stores timestamp in UTC time
|
2016-12-30 23:33:07 +03:00
|
|
|
rows = db_utils.get_javascript_entries(db, all_columns=True)
|
2016-12-15 02:03:25 +03:00
|
|
|
assert len(rows) # make sure we have some JS events captured
|
|
|
|
for row in rows:
|
2020-09-11 16:14:09 +03:00
|
|
|
js_time = datetime.strptime(row["time_stamp"], "%Y-%m-%dT%H:%M:%S.%fZ")
|
2016-12-15 02:03:25 +03:00
|
|
|
# compare UTC now and the timestamp recorded at the visit
|
|
|
|
assert (utc_now - js_time).seconds < MAX_TIMEDELTA
|
2016-12-30 23:33:07 +03:00
|
|
|
assert not db_utils.any_command_failed(db)
|
2016-12-22 01:05:23 +03:00
|
|
|
|
|
|
|
def test_document_cookie_instrumentation(self):
|
|
|
|
db = self.visit(utilities.BASE_TEST_URL + "/js_cookie.html")
|
2016-12-30 23:33:07 +03:00
|
|
|
rows = db_utils.get_javascript_entries(db, all_columns=True)
|
2017-10-10 21:35:13 +03:00
|
|
|
captured_cookie_calls = set()
|
|
|
|
for row in rows:
|
2020-09-11 16:14:09 +03:00
|
|
|
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"],
|
|
|
|
)
|
2017-10-10 21:35:13 +03:00
|
|
|
captured_cookie_calls.add(item)
|
2017-01-05 02:50:29 +03:00
|
|
|
assert captured_cookie_calls == DOCUMENT_COOKIE_READ_WRITE
|