Skip to content

Commit 56f2f05

Browse files
committed
Remove pixel cookie sharing detection for now
1 parent fb5ebfe commit 56f2f05

File tree

4 files changed

+3
-276
lines changed

4 files changed

+3
-276
lines changed

src/js/heuristicblocking.js

+3-162
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,8 @@ HeuristicBlocker.prototype = {
100100
* Use updateTrackerPrevalence for non-webRequest initiated bookkeeping.
101101
*
102102
* @param {Object} details request/response details
103-
* @param {Boolean} check_for_cookie_share whether to check for cookie sharing
104103
*/
105-
heuristicBlockingAccounting: function (details, check_for_cookie_share) {
104+
heuristicBlockingAccounting: function (details) {
106105
// ignore requests that are outside a tabbed window
107106
if (details.tabId < 0 || !incognito.learningEnabled(details.tabId)) {
108107
return {};
@@ -143,119 +142,6 @@ HeuristicBlocker.prototype = {
143142
self._recordPrevalence(request_host, request_origin, tab_origin);
144143
return {};
145144
}
146-
147-
// check for cookie sharing iff this is an image in the top-level frame, and the request URL has parameters
148-
if (check_for_cookie_share && details.type == 'image' && details.frameId === 0 && details.url.indexOf('?') > -1) {
149-
// get all non-HttpOnly cookies for the top-level frame
150-
// and pass those to the cookie-share accounting function
151-
let tab_url = self.tabUrls[details.tabId];
152-
153-
let config = {
154-
url: tab_url
155-
};
156-
if (badger.firstPartyDomainPotentiallyRequired) {
157-
config.firstPartyDomain = null;
158-
}
159-
160-
chrome.cookies.getAll(config, function (cookies) {
161-
cookies = cookies.filter(cookie => !cookie.httpOnly);
162-
if (cookies.length >= 1) {
163-
self.pixelCookieShareAccounting(tab_url, tab_origin, details.url, request_host, request_origin, cookies);
164-
}
165-
});
166-
}
167-
},
168-
169-
/**
170-
* Checks for cookie sharing: requests to third-party domains that include
171-
* high entropy data from first-party cookies (associated with the top-level
172-
* frame). Only catches plain-text verbatim sharing (b64 encoding + the like
173-
* defeat it). Assumes any long string that doesn't contain URL fragments or
174-
* stopwords is an identifier. Doesn't catch cookie syncing (3rd party -> 3rd
175-
* party), but most of those tracking cookies should be blocked anyway.
176-
*
177-
* @param details are those from onBeforeSendHeaders
178-
* @param cookies are the result of chrome.cookies.getAll()
179-
* @returns {*}
180-
*/
181-
pixelCookieShareAccounting: function (tab_url, tab_origin, request_url, request_host, request_origin, cookies) {
182-
let params = (new URL(request_url)).searchParams,
183-
TRACKER_ENTROPY_THRESHOLD = 33,
184-
MIN_STR_LEN = 8;
185-
186-
for (let p of params) {
187-
let key = p[0],
188-
value = p[1];
189-
190-
// the argument must be sufficiently long
191-
if (!value || value.length < MIN_STR_LEN) {
192-
continue;
193-
}
194-
195-
// check if this argument is derived from a high-entropy first-party cookie
196-
for (let cookie of cookies) {
197-
// the cookie value must be sufficiently long
198-
if (!cookie.value || cookie.value.length < MIN_STR_LEN) {
199-
continue;
200-
}
201-
202-
// find the longest common substring between this arg and the cookies
203-
// associated with the document
204-
let substrings = utils.findCommonSubstrings(cookie.value, value) || [];
205-
for (let s of substrings) {
206-
// ignore the substring if it's part of the first-party URL. sometimes
207-
// content servers take the url of the page they're hosting content
208-
// for as an argument. e.g.
209-
// https://example-cdn.com/content?u=http://example.com/index.html
210-
if (tab_url.indexOf(s) != -1) {
211-
continue;
212-
}
213-
214-
// elements of the user agent string are also commonly included in
215-
// both cookies and arguments; e.g. "Mozilla/5.0" might be in both.
216-
// This is not a special tracking risk since third parties can see
217-
// this info anyway.
218-
if (navigator.userAgent.indexOf(s) != -1) {
219-
continue;
220-
}
221-
222-
// Sometimes the entire url and then some is included in the
223-
// substring -- the common string might be "https://example.com/:true"
224-
// In that case, we only care about the information around the URL.
225-
if (s.indexOf(tab_url) != -1) {
226-
s = s.replace(tab_url, "");
227-
}
228-
229-
// During testing we found lots of common values like "homepage",
230-
// "referrer", etc. were being flagged as high entropy. This searches
231-
// for a few of those and removes them before we go further.
232-
let lower = s.toLowerCase();
233-
lowEntropyQueryValues.forEach(function (qv) {
234-
let start = lower.indexOf(qv);
235-
if (start != -1) {
236-
s = s.replace(s.substring(start, start + qv.length), "");
237-
}
238-
});
239-
240-
// at this point, since we might have removed things, make sure the
241-
// string is still long enough to bother with
242-
if (s.length < MIN_STR_LEN) {
243-
continue;
244-
}
245-
246-
// compute the entropy of this common substring. if it's greater than
247-
// our threshold, record the tracking action and exit the function.
248-
let entropy = utils.estimateMaxEntropy(s);
249-
if (entropy > TRACKER_ENTROPY_THRESHOLD) {
250-
log("Found high-entropy cookie share from", tab_origin, "to", request_host,
251-
":", entropy, "bits\n cookie:", cookie.name, '=', cookie.value,
252-
"\n arg:", key, "=", value, "\n substring:", s);
253-
this._recordPrevalence(request_host, request_origin, tab_origin);
254-
return;
255-
}
256-
}
257-
}
258-
}
259145
},
260146

261147
/**
@@ -546,51 +432,6 @@ var lowEntropyCookieValues = {
546432
"zu":8
547433
};
548434

549-
const lowEntropyQueryValues = [
550-
"https",
551-
"http",
552-
"://",
553-
"%3A%2F%2F",
554-
"www",
555-
"url",
556-
"undefined",
557-
"impression",
558-
"session",
559-
"homepage",
560-
"client",
561-
"version",
562-
"business",
563-
"title",
564-
"get",
565-
"site",
566-
"name",
567-
"category",
568-
"account_id",
569-
"smartadserver",
570-
"front",
571-
"page",
572-
"view",
573-
"first",
574-
"visit",
575-
"platform",
576-
"language",
577-
"automatic",
578-
"disabled",
579-
"landing",
580-
"entertainment",
581-
"amazon",
582-
"official",
583-
"webvisor",
584-
"anonymous",
585-
"across",
586-
"narrative",
587-
"\":null",
588-
"\":false",
589-
"\":\"",
590-
"\",\"",
591-
"\",\"",
592-
];
593-
594435
/**
595436
* Extract cookies from onBeforeSendHeaders
596437
*
@@ -680,7 +521,7 @@ function startListeners() {
680521
extraInfoSpec.push('extraHeaders');
681522
}
682523
chrome.webRequest.onBeforeSendHeaders.addListener(function(details) {
683-
return badger.heuristicBlocking.heuristicBlockingAccounting(details, true);
524+
return badger.heuristicBlocking.heuristicBlockingAccounting(details);
684525
}, {urls: ["<all_urls>"]}, extraInfoSpec);
685526

686527
/**
@@ -699,7 +540,7 @@ function startListeners() {
699540
}
700541
}
701542
if (hasSetCookie) {
702-
return badger.heuristicBlocking.heuristicBlockingAccounting(details, false);
543+
return badger.heuristicBlocking.heuristicBlockingAccounting(details);
703544
}
704545
},
705546
{urls: ["<all_urls>"]}, extraInfoSpec);

src/js/utils.js

-43
Original file line numberDiff line numberDiff line change
@@ -200,48 +200,6 @@ function estimateMaxEntropy(str) {
200200
return max_bits;
201201
}
202202

203-
// Adapted from https://gist.github.com/jaewook77/cd1e3aa9449d7ea4fb4f
204-
// Find all common substrings more than 8 characters long, using DYNAMIC
205-
// PROGRAMMING
206-
function findCommonSubstrings(str1, str2) {
207-
/*
208-
Let D[i,j] be the length of the longest matching string suffix between
209-
str1[1]..str1[i] and a segment of str2 between str2[1]..str2[j].
210-
If the ith character in str1 doesn’t match the jth character in str2, then
211-
D[i,j] is zero to indicate that there is no matching suffix
212-
*/
213-
214-
// we only care about strings >= 8 chars
215-
let D = [], LCS = [], LCS_MIN = 8;
216-
217-
// runs in O(M x N) time!
218-
for (let i = 0; i < str1.length; i++) {
219-
D[i] = [];
220-
for (let j = 0; j < str2.length; j++) {
221-
if (str1[i] == str2[j]) {
222-
if (i == 0 || j == 0) {
223-
D[i][j] = 1;
224-
} else {
225-
D[i][j] = D[i-1][j-1] + 1;
226-
}
227-
228-
// store all common substrings longer than the minimum length
229-
if (D[i][j] == LCS_MIN) {
230-
LCS.push(str1.substring(i-D[i][j]+1, i+1));
231-
} else if (D[i][j] > LCS_MIN) {
232-
// remove the shorter substring and add the new, longer one
233-
LCS.pop();
234-
LCS.push(str1.substring(i-D[i][j]+1, i+1));
235-
}
236-
} else {
237-
D[i][j] = 0;
238-
}
239-
}
240-
}
241-
242-
return LCS;
243-
}
244-
245203
function oneSecond() {
246204
return 1000;
247205
}
@@ -468,7 +426,6 @@ let exports = {
468426
arrayBufferToBase64,
469427
estimateMaxEntropy,
470428
explodeSubdomains,
471-
findCommonSubstrings,
472429
getHostFromDomainInput,
473430
isRestrictedUrl,
474431
isThirdPartyDomain,

src/tests/tests/utils.js

-24
Original file line numberDiff line numberDiff line change
@@ -487,30 +487,6 @@ QUnit.test("getHostFromDomainInput", assert => {
487487
);
488488
});
489489

490-
// Tests algorithm used in the pixel tracking heuristic
491-
// It should return a common substring between two given values
492-
QUnit.test("findCommonSubstrings", assert => {
493-
494-
assert.deepEqual(
495-
utils.findCommonSubstrings('www.foo.bar', 'www.foob.ar'),
496-
[],
497-
"substrings under the length threshold of 8 are ignored"
498-
);
499-
500-
assert.equal(
501-
utils.findCommonSubstrings('foobar.com/foo/fizz/buzz/bar', 'foobar.com/foo/bizz/fuzz/bar')[0],
502-
'foobar.com/foo/',
503-
"returns longest matching value from the pair of URLs"
504-
);
505-
506-
assert.deepEqual(
507-
utils.findCommonSubstrings('foobar.com/fizz/buzz/bar/foo', 'foobar.com/fizzbuzz/buzz/bar/foo'),
508-
['foobar.com/fizz', "zz/buzz/bar/foo"],
509-
"returns multiple substrings if multiple are present in comparison"
510-
);
511-
512-
});
513-
514490
// used in pixel tracking heuristic, given a string the estimateMaxEntropy function
515491
// will return the estimated entropy value from it, based on logic parsing the string's length,
516492
// and classes of character complication included in the string

tests/selenium/cookie_sharing_test.py

-47
This file was deleted.

0 commit comments

Comments
 (0)