Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/_locales/en_US/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@
"message": "Prevent WebRTC from leaking local IP address",
"description": "Checkbox label on the general settings page"
},
"options_x_client_data_setting": {
"message": "Remove \"x-client-data\" header from outgoing requests",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should phrase this in a way that's intelligible to non-technical people. Take a look at our existing privacy overrides. Something like Disable sending [NON TECHNICAL DESCRIPTION OF VARIATIONS HEADER DATA] to Google ("X-Client-Data header").

And, yes, exactly, we should also have a "learn more" icon that links to somewhere helpful.

"description": "Checkbox label on the general settings page for removing the x-client-data header on chromium browsers"
},
"intro_welcome": {
"message": "Privacy Badger automatically learns to block invisible trackers. Take a minute to see how.",
"description": "Intro page welcome paragraph."
Expand Down
7 changes: 7 additions & 0 deletions src/js/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ Badger.prototype = {
learnLocally: false,
migrationLevel: 0,
preventWebRTCIPLeak: false,
removeXClientDataHeaders: false,
seenComic: false,
sendDNTSignal: true,
showCounter: true,
Expand Down Expand Up @@ -1125,6 +1126,12 @@ Badger.prototype = {
return this.getSettings().getItem("checkForDNTPolicy");
},

isRemoveXClientDataHeaderEnabled: function() {
if (!chrome.runtime.getBrowserInfo) {
return this.getSettings().getItem("removeXClientDataHeaders");
}
},

isFlocOverwriteEnabled: function() {
if (document.interestCohort) {
return this.getSettings().getItem("disableFloc");
Expand Down
16 changes: 16 additions & 0 deletions src/js/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,22 @@ function loadOptions() {
});
}

// only show the x-client-data header setting if in Chrome & Chromium browsers
// TODO: more accurate way to determine this is a Chrome or Chromium browser
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

X-Client-Data is not in Chromium, only Chrome, I think.

We could try doing feature detection (always better than guessing based on UA). Something like, on Privacy Badger startup, make a dummy request to a Google domain. This request should get cancelled, but before it does, we'll see the headers and set our internal xClientDataHeaderDetected flag.

if (!chrome.runtime.getBrowserInfo) {
$("#remove-x-client-data-toggle").show();
$("#toggle-x-client-data-header-mode")
.prop("checked", OPTIONS_DATA.settings.removeXClientDataHeaders)
.on("click", function () {
const removeXClientDataHeaders = $("#toggle-x-client-data-header-mode").prop("checked");

chrome.runtime.sendMessage({
type: "updateSettings",
data: { removeXClientDataHeaders }
});
});
}

if (OPTIONS_DATA.webRTCAvailable && OPTIONS_DATA.legacyWebRtcProtectionUser) {
$("#webRTCToggle").show();
$("#toggle_webrtc_mode")
Expand Down
14 changes: 9 additions & 5 deletions src/js/webrequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,18 @@ function onBeforeSendHeaders(details) {
type = details.type,
url = details.url;

// option to remove x-client-data headers as well
const removeXClientData = badger.isRemoveXClientDataHeaderEnabled();

if (_isTabChromeInternal(tab_id)) {
// DNT policy requests: strip cookies
if (type == "xmlhttprequest" && url.endsWith("/.well-known/dnt-policy.txt")) {
// remove Cookie headers
let newHeaders = [];

for (let i = 0, count = details.requestHeaders.length; i < count; i++) {
let header = details.requestHeaders[i];
if (header.name.toLowerCase() != "cookie") {
if (header.name.toLowerCase() != "cookie" || (removeXClientData && header.name.toLowerCase() != 'x-client-data')) {
newHeaders.push(header);
}
}
Expand Down Expand Up @@ -256,10 +260,10 @@ function onBeforeSendHeaders(details) {
if (action == constants.COOKIEBLOCK || action == constants.USER_COOKIEBLOCK) {
let newHeaders;

// GET requests: remove cookie headers, reduce referrer header to origin
// GET requests: remove cookie (and x-client-data if option is set) headers, reduce referrer header to origin
if (details.method == "GET") {
newHeaders = details.requestHeaders.filter(header => {
return (header.name.toLowerCase() != "cookie");
return (header.name.toLowerCase() != "cookie" || (removeXClientData && header.name.toLowerCase() != 'x-client-data'));
}).map(header => {
if (header.name.toLowerCase() == "referer") {
header.value = header.value.slice(
Expand All @@ -270,10 +274,10 @@ function onBeforeSendHeaders(details) {
return header;
});

// remove cookie and referrer headers otherwise
// remove cookie, referrer (and x-client-data if option is set) otherwise
} else {
newHeaders = details.requestHeaders.filter(header => {
return (header.name.toLowerCase() != "cookie" && header.name.toLowerCase() != "referer");
return (header.name.toLowerCase() != "cookie" && header.name.toLowerCase() != "referer" && (removeXClientData && header.name.toLowerCase() != 'x-client-data'));
});
}

Expand Down
8 changes: 8 additions & 0 deletions src/skin/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,14 @@ <h4 class="i18n_options_advanced_settings"></h4>
</span>
</label>
</div>
<div class="checkbox" id="remove-x-client-data-toggle" style="display:none">
<label>
<input type="checkbox" id="toggle-x-client-data-header-mode">
<span>
<span class="i18n_options_x_client_data_setting"></span>
</span>
</label>
</div>

</form>
</div>
Expand Down