From 692c22b993da704ff329a3e64c8859ca6d2bb670 Mon Sep 17 00:00:00 2001 From: june wilde Date: Thu, 7 Oct 2021 07:55:30 +0000 Subject: [PATCH] Bug 1670058 - support Global Privacy Control signal; r=smaug,necko-reviewers Differential Revision: https://phabricator.services.mozilla.com/D126966 --- .../client/netmonitor/src/utils/mdn-utils.js | 1 + dom/base/Navigator.cpp | 5 +++ dom/base/Navigator.h | 3 +- dom/security/test/general/file_gpc_server.sjs | 15 +++++++ dom/security/test/general/mochitest.ini | 2 + dom/security/test/general/test_gpc.html | 39 +++++++++++++++++++ dom/webidl/Navigator.webidl | 6 +++ modules/libpref/init/StaticPrefList.yaml | 19 +++++++++ netwerk/protocol/http/nsHttpAtomList.h | 1 + netwerk/protocol/http/nsHttpChannel.cpp | 12 ++++++ netwerk/protocol/http/nsHttpChannel.h | 1 + 11 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 dom/security/test/general/file_gpc_server.sjs create mode 100644 dom/security/test/general/test_gpc.html diff --git a/devtools/client/netmonitor/src/utils/mdn-utils.js b/devtools/client/netmonitor/src/utils/mdn-utils.js index 9bdb7507e653..d7c55821a027 100644 --- a/devtools/client/netmonitor/src/utils/mdn-utils.js +++ b/devtools/client/netmonitor/src/utils/mdn-utils.js @@ -78,6 +78,7 @@ const SUPPORTED_HEADERS = [ "Sec-Fetch-Mode", "Sec-Fetch-Site", "Sec-Fetch-User", + "Sec-GPC", "Server", "Server-Timing", "Set-Cookie", diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index 364ac8dfc6bb..c33df6dd8a4b 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -627,6 +627,11 @@ void Navigator::GetDoNotTrack(nsAString& aResult) { } } +bool Navigator::GlobalPrivacyControl() { + return StaticPrefs::privacy_globalprivacycontrol_enabled() && + StaticPrefs::privacy_globalprivacycontrol_functionality_enabled(); +} + uint64_t Navigator::HardwareConcurrency() { workerinternals::RuntimeService* rts = workerinternals::RuntimeService::GetOrCreateService(); diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index cb7321e409ea..8420679039df 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -129,6 +129,7 @@ class Navigator final : public nsISupports, public nsWrapperCache { nsPluginArray* GetPlugins(ErrorResult& aRv); Permissions* GetPermissions(ErrorResult& aRv); void GetDoNotTrack(nsAString& aResult); + bool GlobalPrivacyControl(); Geolocation* GetGeolocation(ErrorResult& aRv); Promise* GetBattery(ErrorResult& aRv); @@ -289,6 +290,6 @@ class Navigator final : public nsISupports, public nsWrapperCache { RefPtr mLocks; }; -} // namespace mozilla +} // namespace mozilla::dom #endif // mozilla_dom_Navigator_h diff --git a/dom/security/test/general/file_gpc_server.sjs b/dom/security/test/general/file_gpc_server.sjs new file mode 100644 index 000000000000..1a04d49fa2e7 --- /dev/null +++ b/dom/security/test/general/file_gpc_server.sjs @@ -0,0 +1,15 @@ +"use strict"; + +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Cache-Control", "no-cache", false); + + var gpc = request.hasHeader("Sec-GPC") ? request.getHeader("Sec-GPC") : ""; + + if (gpc === "1") { + response.write("true"); + } + else { + response.write("false"); + } +} diff --git a/dom/security/test/general/mochitest.ini b/dom/security/test/general/mochitest.ini index 4d185aa6cb7b..446955a030c5 100644 --- a/dom/security/test/general/mochitest.ini +++ b/dom/security/test/general/mochitest.ini @@ -67,3 +67,5 @@ support-files = [test_bug1660452_http.html] [test_bug1660452_https.html] scheme = https +[test_gpc.html] +support-files = file_gpc_server.sjs diff --git a/dom/security/test/general/test_gpc.html b/dom/security/test/general/test_gpc.html new file mode 100644 index 000000000000..7efccef0d85b --- /dev/null +++ b/dom/security/test/general/test_gpc.html @@ -0,0 +1,39 @@ + + + + Test for Global Privacy Control headers + + + + + + + diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index d2b8177847c3..d07b7c46cb03 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -119,6 +119,12 @@ partial interface Navigator { readonly attribute DOMString doNotTrack; }; +// https://globalprivacycontrol.github.io/gpc-spec/ +partial interface Navigator { + [Pref="privacy.globalprivacycontrol.functionality.enabled"] + readonly attribute boolean globalPrivacyControl; +}; + // http://www.w3.org/TR/geolocation-API/#geolocation_interface interface mixin NavigatorGeolocation { [Throws, Pref="geo.enabled"] diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 329b230a0bf4..edb3fb70d695 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -10326,6 +10326,25 @@ value: false mirror: always +# Potentially send "global privacy control" HTTP header and set navigator +# property accordingly. Communicates user's desire to opt-out/in of +# websites or services selling or sharing the user's information, false by +# default. +# true - Send the header with a value of 1 to indicate opting-out +# false - Do not send header to indicate opting-in +- name: privacy.globalprivacycontrol.enabled + type: bool + value: false + mirror: always + +# Controls whether or not GPC signals are sent. Meant to act as a third option +# of 'undecided' by leaving the navigator property undefined and not attaching +# the Sec-GPC HTTP header. +- name: privacy.globalprivacycontrol.functionality.enabled + type: bool + value: false + mirror: always + # Lower the priority of network loads for resources on the tracking protection # list. Note that this requires the # privacy.trackingprotection.annotate_channels pref to be on in order to have diff --git a/netwerk/protocol/http/nsHttpAtomList.h b/netwerk/protocol/http/nsHttpAtomList.h index 40c7e7da0232..1b01786047e0 100644 --- a/netwerk/protocol/http/nsHttpAtomList.h +++ b/netwerk/protocol/http/nsHttpAtomList.h @@ -52,6 +52,7 @@ HTTP_ATOM(ETag, "Etag") HTTP_ATOM(Expect, "Expect") HTTP_ATOM(Expires, "Expires") HTTP_ATOM(From, "From") +HTTP_ATOM(GlobalPrivacyControl, "Sec-GPC") HTTP_ATOM(Host, "Host") HTTP_ATOM(If, "If") HTTP_ATOM(If_Match, "If-Match") diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index ff78e3ca15f5..68b542a84817 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -5997,6 +5997,7 @@ nsresult nsHttpChannel::BeginConnect() { SetOriginHeader(); SetDoNotTrack(); + SetGlobalPrivacyControl(); OriginAttributes originAttributes; // Regular principal in case we have a proxy. @@ -8704,6 +8705,17 @@ void nsHttpChannel::SetDoNotTrack() { } } +void nsHttpChannel::SetGlobalPrivacyControl() { + MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread"); + + if (StaticPrefs::privacy_globalprivacycontrol_enabled() && + StaticPrefs::privacy_globalprivacycontrol_functionality_enabled()) { + // Send the header with a value of 1 to indicate opting-out + DebugOnly rv = + mRequestHead.SetHeader(nsHttp::GlobalPrivacyControl, "1"_ns, false); + } +} + void nsHttpChannel::ReportRcwnStats(bool isFromNet) { if (!StaticPrefs::network_http_rcwn_enabled()) { return; diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 20d85cdda341..62efd4c4decf 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -502,6 +502,7 @@ class nsHttpChannel final : public HttpBaseChannel, void SetOriginHeader(); void SetDoNotTrack(); + void SetGlobalPrivacyControl(); already_AddRefed GetOrCreateChannelClassifier();