Skip to content

Commit de00f9e

Browse files
committed
Remove pixel cookie sharing detection for now
1 parent 236e304 commit de00f9e

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

263149
/**
@@ -548,51 +434,6 @@ var lowEntropyCookieValues = {
548434
"zu":8
549435
};
550436

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

688529
/**
@@ -701,7 +542,7 @@ function startListeners() {
701542
}
702543
}
703544
if (hasSetCookie) {
704-
return badger.heuristicBlocking.heuristicBlockingAccounting(details, false);
545+
return badger.heuristicBlocking.heuristicBlockingAccounting(details);
705546
}
706547
},
707548
{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)