From: uazo Date: Wed, 21 Sep 2022 12:28:17 +0000 Subject: Remove HTTP referrals in cross origin navigation The patch removes the referrals if the navigation is cross-origin and occurs in the top frame. The value is not removed across iframes because the referrals are statically defined by the HTML and the Javascript of the page, and therefore they do not tell anything about the user. Also, some services may not work, such as video iframes. A preference is also introduced to completely removes referrals management, for advanced users. Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html --- chrome/android/chrome_java_resources.gni | 2 + chrome/android/chrome_java_sources.gni | 2 + ...button_group_referer_policy_preference.xml | 47 +++++++++ .../java/res/xml/privacy_preferences.xml | 4 + .../res/xml/referer_policy_preferences.xml | 31 ++++++ .../privacy/settings/PrivacySettings.java | 6 ++ .../RadioButtonGroupRefererSettings.java | 89 +++++++++++++++++ .../settings/RefererSettingsFragment.java | 98 +++++++++++++++++++ .../api/settings_private/prefs_util.cc | 5 + .../net/system_network_context_manager.cc | 4 + chrome/browser/renderer_preferences_util.cc | 1 + .../settings/privacy_page/privacy_page.html | 10 ++ .../settings/privacy_page/privacy_page.ts | 18 ++++ .../strings/android_chrome_strings.grd | 24 +++++ chrome/browser/ui/prefs/pref_watcher.cc | 2 + chrome/browser/ui/prefs/prefs_tab_helper.cc | 2 + .../settings_localized_strings_provider.cc | 4 + chrome/common/pref_names.h | 3 + ...-referrals-in-cross-origin-navigation.grdp | 18 ++++ .../content/internal/context_menu_download.cc | 10 ++ .../renderer_host/navigation_request.cc | 9 ++ .../network/public/cpp/resource_request.h | 2 +- .../renderer_preferences.h | 1 + 23 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 chrome/android/java/res/layout/radio_button_group_referer_policy_preference.xml create mode 100644 chrome/android/java/res/xml/referer_policy_preferences.xml create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/RadioButtonGroupRefererSettings.java create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/RefererSettingsFragment.java create mode 100644 components/cromite_components_strings_grd/Remove-HTTP-referrals-in-cross-origin-navigation.grdp diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni @@ -675,6 +675,8 @@ chrome_java_resources = [ "java/res/xml/personalize_google_services_preferences.xml", "java/res/xml/incognito_preferences.xml", "java/res/xml/privacy_preferences.xml", + "java/res/xml/referer_policy_preferences.xml", + "java/res/layout/radio_button_group_referer_policy_preference.xml", "java/res/xml/search_widget_info.xml", "java/res/xml/tracing_preferences.xml", "java/res/xml/unified_account_settings_preferences.xml", diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni @@ -1011,6 +1011,8 @@ chrome_java_sources = [ "java/src/org/chromium/chrome/browser/privacy/settings/IncognitoSettings.java", "java/src/org/chromium/chrome/browser/privacy_sandbox/CctHandler.java", "java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandbox3pcdRollbackMessageController.java", + "java/src/org/chromium/chrome/browser/privacy/settings/RefererSettingsFragment.java", + "java/src/org/chromium/chrome/browser/privacy/settings/RadioButtonGroupRefererSettings.java", "java/src/org/chromium/chrome/browser/provider/BaseColumns.java", "java/src/org/chromium/chrome/browser/provider/BookmarkColumns.java", "java/src/org/chromium/chrome/browser/provider/ChromeBrowserProviderImpl.java", diff --git a/chrome/android/java/res/layout/radio_button_group_referer_policy_preference.xml b/chrome/android/java/res/layout/radio_button_group_referer_policy_preference.xml new file mode 100644 --- /dev/null +++ b/chrome/android/java/res/layout/radio_button_group_referer_policy_preference.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml --- a/chrome/android/java/res/xml/privacy_preferences.xml +++ b/chrome/android/java/res/xml/privacy_preferences.xml @@ -112,6 +112,10 @@ found in the LICENSE file. android:title="@string/close_tabs_on_exit_title" android:summary="@string/close_tabs_on_exit_summary" android:defaultValue="false" /> + diff --git a/chrome/android/java/res/xml/referer_policy_preferences.xml b/chrome/android/java/res/xml/referer_policy_preferences.xml new file mode 100644 --- /dev/null +++ b/chrome/android/java/res/xml/referer_policy_preferences.xml @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java --- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java @@ -44,6 +44,7 @@ import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.prefetch.settings.PreloadPagesSettingsFragment; +import org.chromium.chrome.browser.privacy.settings.RefererSettingsFragment; import org.chromium.chrome.browser.privacy.secure_dns.SecureDnsSettings; import org.chromium.chrome.browser.privacy_guide.PrivacyGuideFragment; import org.chromium.chrome.browser.privacy_guide.PrivacyGuideInteractions; @@ -123,6 +124,7 @@ public class PrivacySettings extends ChromeBaseSettingsFragment private static final String PREF_SAFE_BROWSING = "safe_browsing"; private static final String PREF_PASSWORD_LEAK_DETECTION = "password_leak_detection"; private static final String PREF_SYNC_AND_SERVICES_LINK = "sync_and_services_link"; + private static final String PREF_REFERER_POLICY = "referers_policy"; private static final String PREF_PRIVACY_SANDBOX = "privacy_sandbox"; private static final String PREF_PROXY_OPTIONS = "proxy"; private static final String PREF_PRIVACY_GUIDE = "privacy_guide"; @@ -571,6 +573,10 @@ public class PrivacySettings extends ChromeBaseSettingsFragment : R.string.text_off); } + Preference refererPolicyPref = findPreference(PREF_REFERER_POLICY); + refererPolicyPref.setSummary( + RefererSettingsFragment.getRefererSummaryString(getContext())); + Preference preloadPagesPreference = findPreference(PREF_PRELOAD_PAGES); if (preloadPagesPreference != null) { preloadPagesPreference.setSummary( diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/RadioButtonGroupRefererSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/RadioButtonGroupRefererSettings.java new file mode 100644 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/RadioButtonGroupRefererSettings.java @@ -0,0 +1,89 @@ +/* + This file is part of Bromite. + + Bromite is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bromite is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bromite. If not, see . +*/ + +package org.chromium.chrome.browser.privacy.settings; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.RadioGroup; + +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.components.browser_ui.widget.RadioButtonWithDescription; +import org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout; + +public class RadioButtonGroupRefererSettings extends Preference + implements RadioGroup.OnCheckedChangeListener { + + private RadioButtonWithDescription mStandardReferer; + private RadioButtonWithDescription mNoCrossOriginReferer; + private RadioButtonWithDescription mNoReferer; + private int mRefererPolicy; + + public RadioButtonGroupRefererSettings(Context context, AttributeSet attrs) { + super(context, attrs); + setLayoutResource(R.layout.radio_button_group_referer_policy_preference); + } + + public void init(boolean enableReferer, int refererPolicy) { + if (!enableReferer) + mRefererPolicy = 0; + else + mRefererPolicy = refererPolicy; + } + + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + if (checkedId == mStandardReferer.getId()) { + mRefererPolicy = 1; + } else if (checkedId == mNoCrossOriginReferer.getId()) { + mRefererPolicy = 2; + } else if (checkedId == mNoReferer.getId()) { + mRefererPolicy = 0; + } else { + assert false : "Should not be reached."; + } + callChangeListener(mRefererPolicy); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + mStandardReferer = (RadioButtonWithDescription) holder.findViewById( + R.id.standard_referer_policy); + mNoCrossOriginReferer = (RadioButtonWithDescription) holder.findViewById( + R.id.no_cross_origin_top_frame_policy); + mNoReferer = (RadioButtonWithDescription) holder.findViewById(R.id.disable_referer_policy); + + RadioButtonWithDescriptionLayout groupLayout = + (RadioButtonWithDescriptionLayout) mNoReferer.getRootView(); + setCheckedState(mRefererPolicy); + groupLayout.setOnCheckedChangeListener(this); + } + + public void setCheckedState(int checkedState) { + mRefererPolicy = checkedState; + mStandardReferer.setChecked(checkedState == 1); + mNoCrossOriginReferer.setChecked(checkedState == 2); + mNoReferer.setChecked(checkedState == 0); + } +} diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/RefererSettingsFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/RefererSettingsFragment.java new file mode 100644 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/RefererSettingsFragment.java @@ -0,0 +1,98 @@ +/* + This file is part of Bromite. + + Bromite is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bromite is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bromite. If not, see . +*/ + +package org.chromium.chrome.browser.privacy.settings; + +import android.os.Bundle; +import android.content.Context; + +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; + +import org.chromium.base.supplier.MonotonicObservableSupplier; +import org.chromium.base.supplier.ObservableSuppliers; +import org.chromium.base.supplier.SettableMonotonicObservableSupplier; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.profiles.ProfileManager; +import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment; +import org.chromium.components.browser_ui.settings.SettingsFragment; +import org.chromium.components.browser_ui.settings.SettingsUtils; +import org.chromium.components.browser_ui.settings.TextMessagePreference; +import org.chromium.components.prefs.PrefService; +import org.chromium.components.user_prefs.UserPrefs; + +public class RefererSettingsFragment extends ChromeBaseSettingsFragment + implements Preference.OnPreferenceChangeListener { + + static final String PREF_REFERER_POLICY = "referer_page_radio_button_group"; + + private RadioButtonGroupRefererSettings mRefererPreference; + private final PrefService prefService = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); + + private final SettableMonotonicObservableSupplier mPageTitle = + ObservableSuppliers.createMonotonic(); + + public static String getRefererSummaryString(Context context) { + int policy = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()) + .getInteger(Pref.REFERRERS_POLICY); + + if (policy == 0) { + return context.getString(R.string.disable_referer_policy_title); + } + if (policy == 1) { + return context.getString(R.string.standard_referer_policy_title); + } + if (policy == 2) { + return context.getString(R.string.no_cross_origin_top_frame_policy_title); + } + assert false : "Should not be reached"; + return ""; + } + + @Override + public @SettingsFragment.AnimationType int getAnimationType() { + return SettingsFragment.AnimationType.PROPERTY; + } + + @Override + public MonotonicObservableSupplier getPageTitle() { + return mPageTitle; + } + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + SettingsUtils.addPreferencesFromResource(this, R.xml.referer_policy_preferences); + getActivity().setTitle(R.string.referers_policy_title); + + mRefererPreference = findPreference(PREF_REFERER_POLICY); + mRefererPreference.init(prefService.getBoolean(Pref.ENABLE_REFERRERS), + prefService.getInteger(Pref.REFERRERS_POLICY)); + mRefererPreference.setOnPreferenceChangeListener(this); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + UserPrefs.get(ProfileManager.getLastUsedRegularProfile()) + .setInteger(Pref.REFERRERS_POLICY, (int)newValue); + UserPrefs.get(ProfileManager.getLastUsedRegularProfile()) + .setBoolean(Pref.ENABLE_REFERRERS, (int)newValue != 0); + return true; + } +} diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc @@ -275,6 +275,11 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() { (*s_allowlist)[::prefs::kExpireDaysThreshold] = settings_api::PrefType::kNumber; + (*s_allowlist)[::prefs::kEnableReferrers] = + settings_api::PrefType::kBoolean; + (*s_allowlist)[::prefs::kReferrersPolicy] = + settings_api::PrefType::kNumber; + // Appearance settings. (*s_allowlist)[::prefs::kCurrentThemeID] = settings_api::PrefType::kString; (*s_allowlist)[::prefs::kPinnedActions] = settings_api::PrefType::kList; diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc @@ -675,6 +675,9 @@ SystemNetworkContextManager::SystemNetworkContextManager( base::BindRepeating(&SystemNetworkContextManager::UpdateReferrersEnabled, base::Unretained(this))); + local_state_->SetDefaultPrefValue( + prefs::kReferrersPolicy, base::Value(2)); + pref_change_registrar_.Add( prefs::kExplicitlyAllowedNetworkPorts, base::BindRepeating( @@ -757,6 +760,7 @@ void SystemNetworkContextManager::RegisterPrefs(PrefRegistrySimple* registry) { // the system NetworkContext, and the per-profile pref values are used for // the profile NetworkContexts. registry->RegisterBooleanPref(prefs::kEnableReferrers, true); + registry->RegisterIntegerPref(prefs::kReferrersPolicy, 2); registry->RegisterBooleanPref(prefs::kQuickCheckEnabled, true); diff --git a/chrome/browser/renderer_preferences_util.cc b/chrome/browser/renderer_preferences_util.cc --- a/chrome/browser/renderer_preferences_util.cc +++ b/chrome/browser/renderer_preferences_util.cc @@ -150,6 +150,7 @@ void UpdateFromSystemSettings(blink::RendererPreferences* prefs, prefs->caret_blink_interval = ui::NativeTheme::GetInstanceForNativeUi()->caret_blink_interval(); prefs->enable_referrers = pref_service->GetBoolean(prefs::kEnableReferrers); + prefs->referrers_policy = pref_service->GetInteger(prefs::kReferrersPolicy); prefs->enable_do_not_track = pref_service->GetBoolean(prefs::kEnableDoNotTrack); prefs->enable_encrypted_media = diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html @@ -64,6 +64,16 @@ menu-options="[[historyExpireDaysThresholdOptions_]]"> +
+ + + +
[[dbdDeletionConfirmationToastLabel_]]
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.ts b/chrome/browser/resources/settings/privacy_page/privacy_page.ts --- a/chrome/browser/resources/settings/privacy_page/privacy_page.ts +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.ts @@ -88,6 +88,17 @@ export class SettingsPrivacyPageElement extends SettingsPrivacyPageElementBase { value: () => loadTimeData.getBoolean('isPrivacySandboxRestricted'), }, + referersPolicyOptions_: { + readOnly: true, + type: Array, + value() { + return [ + {value: 2, name: loadTimeData.getString('noCrossOriginTopFramePolicy')}, + {value: 1, name: loadTimeData.getString('standardRefererPolicy')}, + {value: 0, name: loadTimeData.getString('disableRefererPolicy')}, + ]; + }, + }, isPrivacySandboxRestrictedNoticeEnabled_: { type: Boolean, value: () => @@ -116,6 +127,7 @@ export class SettingsPrivacyPageElement extends SettingsPrivacyPageElementBase { declare private historyExpireDaysThresholdOptions_: object[]; declare private showClearBrowsingDataDialog_: boolean; declare private showPrivacyGuideDialog_: boolean; + declare private referersPolicyOptions_: object[]; declare private isPrivacySandboxRestricted_: boolean; declare private isPrivacySandboxRestrictedNoticeEnabled_: boolean; declare private isAdPrivacyAvailable_: boolean; @@ -147,6 +159,12 @@ export class SettingsPrivacyPageElement extends SettingsPrivacyPageElementBase { Router.getInstance().navigateTo(routes.COOKIES); } + private onReferersPolicyChanged_(): void { + const policy = + this.getPref('referrers_policy').value; + this.setPrefValue('enable_referrers', policy != 0); + } + private onCbdDialogClosed_() { Router.getInstance().navigateTo(routes.CLEAR_BROWSER_DATA.parent!); diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd @@ -1235,6 +1235,30 @@ For more settings that use data to improve your Chrome experience, go to + + HTTP Referer header policy + + + Allow to change default HTTP Referer header policy + + + Standard HTTP Referrer header policy + + + Send only origin if the request is cross-origin + + + Disable if cross-origin and user begins navigation + + + Remove referrer if the navigation is cross-origin and occurs in the top frame otherwise send only origin if the request is cross-origin + + + Disable all referrers + + + Disable all referrers, may break navigation + Access payment methods diff --git a/chrome/browser/ui/prefs/pref_watcher.cc b/chrome/browser/ui/prefs/pref_watcher.cc --- a/chrome/browser/ui/prefs/pref_watcher.cc +++ b/chrome/browser/ui/prefs/pref_watcher.cc @@ -134,6 +134,8 @@ PrefWatcher::PrefWatcher(Profile* profile) : profile_(profile) { renderer_callback); profile_pref_change_registrar_.Add(prefs::kEnableReferrers, renderer_callback); + profile_pref_change_registrar_.Add(prefs::kReferrersPolicy, + renderer_callback); profile_pref_change_registrar_.Add(prefs::kEnableEncryptedMedia, renderer_callback); profile_pref_change_registrar_.Add(prefs::kWebRTCIPHandlingPolicy, diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.cc b/chrome/browser/ui/prefs/prefs_tab_helper.cc --- a/chrome/browser/ui/prefs/prefs_tab_helper.cc +++ b/chrome/browser/ui/prefs/prefs_tab_helper.cc @@ -384,6 +384,8 @@ void PrefsTabHelper::RegisterProfilePrefs( registry->RegisterBooleanPref( prefs::kEnableReferrers, !base::FeatureList::IsEnabled(features::kNoReferrers)); + registry->RegisterIntegerPref( + prefs::kReferrersPolicy, 2); // NoCrossOriginReferer registry->RegisterBooleanPref(prefs::kEnableEncryptedMedia, true); registry->RegisterBooleanPref(prefs::kScrollToTextFragmentEnabled, false); #if BUILDFLAG(IS_ANDROID) diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc @@ -2344,6 +2344,10 @@ void AddPrivacyStrings(content::WebUIDataSource* html_source, {"dayHistory", IDS_SETTINGS_DAY_HISTORY_DESCRIPTION}, {"daysHistory", IDS_SETTINGS_DAYS_HISTORY_DESCRIPTION}, {"foreverHistory", IDS_SETTINGS_FOREVER_HISTORY_DESCRIPTION}, + {"referersPolicyTitle", IDS_REFERERS_POLICY_TITLE}, + {"standardRefererPolicy", IDS_STANDARD_REFERER_POLICY_TITLE}, + {"noCrossOriginTopFramePolicy", IDS_NO_CROSS_ORIGIN_TOP_FRAME_POLICY_TITLE}, + {"disableRefererPolicy", IDS_DISABLE_REFERER_POLICY_TITLE}, #if BUILDFLAG(GOOGLE_CHROME_BRANDING) {"safeBrowsingStandardDescProxy", IDS_SETTINGS_SAFEBROWSING_STANDARD_DESC_PROXY}, diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -1105,6 +1105,9 @@ inline constexpr char kEnableDoNotTrack[] = "enable_do_not_track"; inline constexpr char kEnableEncryptedMedia[] = "webkit.webprefs.encrypted_media_enabled"; +// Set referrer policy. +inline constexpr char kReferrersPolicy[] = "referrers_policy"; + // Boolean that specifies whether to import the form data for autofill from the // default browser on first run. inline constexpr char kImportAutofillFormData[] = "import_autofill_form_data"; diff --git a/components/cromite_components_strings_grd/Remove-HTTP-referrals-in-cross-origin-navigation.grdp b/components/cromite_components_strings_grd/Remove-HTTP-referrals-in-cross-origin-navigation.grdp new file mode 100644 --- /dev/null +++ b/components/cromite_components_strings_grd/Remove-HTTP-referrals-in-cross-origin-navigation.grdp @@ -0,0 +1,18 @@ + + + + HTTP Referer header policy + + + Allow to change default HTTP Referer header policy + + + Standard HTTP Referrer header policy + + + Disable if cross-origin and user begins navigation (default) + + + Disable all referrers + + diff --git a/components/download/content/internal/context_menu_download.cc b/components/download/content/internal/context_menu_download.cc --- a/components/download/content/internal/context_menu_download.cc +++ b/components/download/content/internal/context_menu_download.cc @@ -12,6 +12,8 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/referrer.h" #include "net/traffic_annotation/network_traffic_annotation.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" namespace download { @@ -31,6 +33,14 @@ void CreateContextMenuDownload(const GURL& url, content::Referrer referrer = content::Referrer::SanitizeForRequest( url, content::Referrer(referring_url.GetAsReferrer(), params.referrer_policy)); + blink::RendererPreferences* render_prefs = web_contents->GetMutableRendererPrefs(); + if (render_prefs->enable_referrers && render_prefs->referrers_policy == 2 && + !net::registry_controlled_domains::SameDomainOrHost( + referring_url, url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)) { + referrer = content::Referrer::SanitizeForRequest( + url, + content::Referrer(params.page_url.GetAsReferrer(), params.referrer_policy)); + } dl_params->set_referrer(referrer.url); dl_params->set_referrer_policy( content::Referrer::ReferrerPolicyForUrlRequest(referrer.policy)); diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc @@ -403,6 +403,15 @@ void AddAdditionalRequestHeaders( blink::mojom::Referrer(GURL(), network::mojom::ReferrerPolicy::kNever); } + if (render_prefs.enable_referrers && render_prefs.referrers_policy == 2 && + !net::registry_controlled_domains::SameDomainOrHost( + referrer->url, url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES) && + frame_tree_node->IsOutermostMainFrame()) { + // remove referrer if the navigation is done on the top frame + *referrer = + blink::mojom::Referrer(GURL(), network::mojom::ReferrerPolicy::kNever); + } + // Next, set the HTTP Origin if needed. std::optional existing_origin = headers->GetHeader(net::HttpRequestHeaders::kOrigin); diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h --- a/services/network/public/cpp/resource_request.h +++ b/services/network/public/cpp/resource_request.h @@ -215,7 +215,7 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) ResourceRequest { std::vector navigation_redirect_chain; GURL referrer; - net::ReferrerPolicy referrer_policy = net::ReferrerPolicy::NEVER_CLEAR; + net::ReferrerPolicy referrer_policy = net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN; net::HttpRequestHeaders headers; net::HttpRequestHeaders cors_exempt_headers; int load_flags = 0; diff --git a/third_party/blink/public/common/renderer_preferences/renderer_preferences.h b/third_party/blink/public/common/renderer_preferences/renderer_preferences.h --- a/third_party/blink/public/common/renderer_preferences/renderer_preferences.h +++ b/third_party/blink/public/common/renderer_preferences/renderer_preferences.h @@ -50,6 +50,7 @@ struct BLINK_COMMON_EXPORT RendererPreferences { std::optional caret_blink_interval; bool use_custom_colors{true}; bool enable_referrers{true}; + uint32_t referrers_policy{2}; bool allow_cross_origin_auth_prompt{false}; bool enable_do_not_track{false}; bool enable_encrypted_media{true}; --