feat: add experimental cookie encryption support (#27524)

* feat: add experimental cookie encryption support on macOS

* chore: fix TODO

* update patches

* feat: make cookie encryption work on windows

* chore: update cookie encryption support comments

* fix: only call OSCrypt::Init on windows

* chore: make cookie encryption work on linux

* Update shell/browser/net/system_network_context_manager.cc

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

* chore: fix lint

* chore: update patches

* chore: update patches to upstreamed variants

* chore: use chrome ::switches constants

* chore: remove bad patch

* build: disable cookie encryption by default

* chore: update patches

* fix: provide std::string to NoDestructor

* chore: fix macos, nodestructor syntax

* build: fix macOS build due to mismatch in DEFINE

Co-authored-by: Electron Bot <electron@github.com>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
This commit is contained in:
Samuel Attard 2021-05-26 12:16:55 -07:00 committed by GitHub
parent f01e35f4ea
commit 7984933e9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 389 additions and 11 deletions

View file

@ -9,8 +9,12 @@
#include <utility>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "chrome/common/chrome_switches.h"
#include "components/os_crypt/os_crypt.h"
#include "components/prefs/in_memory_pref_store.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/overlay_user_pref_store.h"
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_registry_simple.h"
@ -20,11 +24,13 @@
#include "components/proxy_config/proxy_config_pref_names.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/common/content_switches.h"
#include "electron/fuses.h"
#include "extensions/common/constants.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_config_with_annotation.h"
#include "services/network/public/cpp/network_switches.h"
#include "shell/common/electron_paths.h"
#if BUILDFLAG(ENABLE_PRINTING)
#include "chrome/browser/printing/print_job_manager.h"
@ -83,15 +89,32 @@ BuildState* BrowserProcessImpl::GetBuildState() {
}
void BrowserProcessImpl::PostEarlyInitialization() {
// Mock user prefs, as we only need to track changes for a
// in memory pref store. There are no persistent preferences
PrefServiceFactory prefs_factory;
auto pref_registry = base::MakeRefCounted<PrefRegistrySimple>();
PrefProxyConfigTrackerImpl::RegisterPrefs(pref_registry.get());
#if defined(OS_WIN)
OSCrypt::RegisterLocalPrefs(pref_registry.get());
#endif
auto pref_store = base::MakeRefCounted<ValueMapPrefStore>();
ApplyProxyModeFromCommandLine(pref_store.get());
prefs_factory.set_command_line_prefs(std::move(pref_store));
prefs_factory.set_user_prefs(new OverlayUserPrefStore(new InMemoryPrefStore));
// Only use a persistent prefs store when cookie encryption is enabled as that
// is the only key that needs it
if (electron::fuses::IsCookieEncryptionEnabled()) {
base::FilePath prefs_path;
CHECK(base::PathService::Get(electron::DIR_USER_DATA, &prefs_path));
prefs_path = prefs_path.Append(FILE_PATH_LITERAL("Local State"));
base::ThreadRestrictions::ScopedAllowIO allow_io;
scoped_refptr<JsonPrefStore> user_pref_store =
base::MakeRefCounted<JsonPrefStore>(prefs_path);
user_pref_store->ReadPrefs();
prefs_factory.set_user_prefs(user_pref_store);
} else {
prefs_factory.set_user_prefs(
new OverlayUserPrefStore(new InMemoryPrefStore));
}
local_state_ = prefs_factory.Create(std::move(pref_registry));
}

View file

@ -17,6 +17,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/icon_manager.h"
#include "components/os_crypt/os_crypt.h"
#include "content/browser/browser_main_loop.h" // nogncheck
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
@ -26,6 +27,7 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "electron/buildflags/buildflags.h"
#include "electron/fuses.h"
#include "media/base/localized_strings.h"
#include "services/network/public/cpp/features.h"
#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h"
@ -538,6 +540,16 @@ void ElectronBrowserMainParts::PreCreateMainMessageLoopCommon() {
RegisterURLHandler();
#endif
media::SetLocalizedStringProvider(MediaStringProvider);
#if defined(OS_WIN)
if (electron::fuses::IsCookieEncryptionEnabled()) {
auto* local_state = g_browser_process->local_state();
DCHECK(local_state);
bool os_crypt_init = OSCrypt::Init(local_state);
DCHECK(os_crypt_init);
}
#endif
}
device::mojom::GeolocationControl*

View file

@ -9,6 +9,7 @@
#include "chrome/common/chrome_constants.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
#include "electron/fuses.h"
#include "net/net_buildflags.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/cors/origin_access_list.h"
@ -77,9 +78,8 @@ void NetworkContextService::ConfigureNetworkContextParams(
network_context_params->restore_old_session_cookies = false;
network_context_params->persist_session_cookies = false;
// TODO(deepak1556): Matches the existing behavior https://git.io/fxHMl,
// enable encryption as a followup.
network_context_params->enable_encrypted_cookies = false;
network_context_params->enable_encrypted_cookies =
electron::fuses::IsCookieEncryptionEnabled();
network_context_params->transport_security_persister_path = path;
}

View file

@ -8,11 +8,16 @@
#include <utility>
#include "base/command_line.h"
#include "base/path_service.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
#include "chrome/common/chrome_switches.h"
#include "components/os_crypt/os_crypt.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_features.h"
#include "content/public/common/network_service_util.h"
#include "electron/fuses.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "net/net_buildflags.h"
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
@ -21,11 +26,17 @@
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "shell/browser/browser.h"
#include "shell/browser/electron_browser_client.h"
#include "shell/common/application_info.h"
#include "shell/common/electron_paths.h"
#include "shell/common/options_switches.h"
#include "url/gurl.h"
#if defined(OS_MAC)
#include "components/os_crypt/keychain_password_mac.h"
#endif
namespace {
// The global instance of the SystemNetworkContextmanager.
@ -218,6 +229,39 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(
network_service->CreateNetworkContext(
network_context_.BindNewPipeAndPassReceiver(),
CreateNetworkContextParams());
if (electron::fuses::IsCookieEncryptionEnabled()) {
std::string app_name = electron::Browser::Get()->GetName();
#if defined(OS_MAC)
*KeychainPassword::service_name = app_name + " Safe Storage";
*KeychainPassword::account_name = app_name;
#endif
// The OSCrypt keys are process bound, so if network service is out of
// process, send it the required key.
if (content::IsOutOfProcessNetworkService()) {
#if defined(OS_LINUX)
// c.f.
// https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/net/system_network_context_manager.cc;l=515;drc=9d82515060b9b75fa941986f5db7390299669ef1;bpv=1;bpt=1
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
network::mojom::CryptConfigPtr config =
network::mojom::CryptConfig::New();
config->application_name = app_name;
config->product_name = app_name;
// c.f.
// https://source.chromium.org/chromium/chromium/src/+/master:chrome/common/chrome_switches.cc;l=689;drc=9d82515060b9b75fa941986f5db7390299669ef1
config->store =
command_line.GetSwitchValueASCII(::switches::kPasswordStore);
config->should_use_preference =
command_line.HasSwitch(::switches::kEnableEncryptionSelection);
base::PathService::Get(electron::DIR_USER_DATA, &config->user_data_path);
network_service->SetCryptConfig(std::move(config));
#else
network_service->SetEncryptionKey(OSCrypt::GetRawEncryptionKey());
#endif
}
}
}
network::mojom::NetworkContextParamsPtr