From c9f6debc7174d10e0fb53fa0fd2f5a834a3c4944 Mon Sep 17 00:00:00 2001 From: Michael Herrmann Date: Mon, 29 Sep 2025 16:54:35 +0200 Subject: [PATCH] Improve update request privacy (#31127) * Don't send any contents of the hw object * Never send app/lang * Don't send download_time_ms The motivation is that these could otherwise potentially be used to fingerprint users. --- BUILD.gn | 3 + DEPS | 2 +- chromium_src/chrome/updater/DEPS | 3 + chromium_src/chrome/updater/configurator.cc | 10 +++ .../chrome/updater/ping_configurator.cc | 10 +++ .../components/component_updater/DEPS | 1 + .../component_updater/configurator_impl.cc | 4 + components/BUILD.gn | 2 + components/component_updater/BUILD.gn | 16 ++++ components/component_updater/DEPS | 4 + .../configurator_impl_unittest.cc | 30 +++++++ components/update_client/BUILD.gn | 28 ++++++ components/update_client/DEPS | 10 +++ .../privacy_preserving_protocol_handler.cc | 27 ++++++ .../privacy_preserving_protocol_handler.h | 29 +++++++ ...cy_preserving_protocol_handler_unittest.cc | 17 ++++ .../privacy_preserving_protocol_serializer.cc | 65 ++++++++++++++ .../privacy_preserving_protocol_serializer.h | 34 ++++++++ components/update_client/sources.gni | 7 ++ components/update_client/test_util.cc | 86 +++++++++++++++++++ components/update_client/test_util.h | 17 ++++ .../components-update_client-BUILD.gn.patch | 4 +- updater/BUILD.gn | 27 ++++++ updater/DEPS | 6 ++ updater/configurator_unittest.cc | 49 +++++++++++ updater/ping_configurator_unittest.cc | 27 ++++++ updater/run_all_unittests.cc | 15 ++++ 27 files changed, 530 insertions(+), 3 deletions(-) create mode 100644 chromium_src/chrome/updater/DEPS create mode 100644 chromium_src/chrome/updater/configurator.cc create mode 100644 chromium_src/chrome/updater/ping_configurator.cc create mode 100644 components/component_updater/BUILD.gn create mode 100644 components/component_updater/DEPS create mode 100644 components/component_updater/configurator_impl_unittest.cc create mode 100644 components/update_client/DEPS create mode 100644 components/update_client/privacy_preserving_protocol_handler.cc create mode 100644 components/update_client/privacy_preserving_protocol_handler.h create mode 100644 components/update_client/privacy_preserving_protocol_handler_unittest.cc create mode 100644 components/update_client/privacy_preserving_protocol_serializer.cc create mode 100644 components/update_client/privacy_preserving_protocol_serializer.h create mode 100644 components/update_client/test_util.cc create mode 100644 components/update_client/test_util.h create mode 100644 updater/BUILD.gn create mode 100644 updater/DEPS create mode 100644 updater/configurator_unittest.cc create mode 100644 updater/ping_configurator_unittest.cc create mode 100644 updater/run_all_unittests.cc diff --git a/BUILD.gn b/BUILD.gn index ac99eebb8e1..dea9cd3c79b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -87,6 +87,9 @@ if (!is_ios) { if (!is_ios && !is_android) { brave_all_unit_tests_deps += [ "//brave/test:brave_installer_unittests" ] } +if (is_win || is_mac || is_linux) { + brave_all_unit_tests_deps += [ "//brave/updater:brave_updater_unittests" ] +} # This group is for unit tests that run as part of brave_all_unit_tests. Other # tests that you only want to build should be added directly to `all` group diff --git a/DEPS b/DEPS index dd73f06fdd8..5a51eac20b9 100644 --- a/DEPS +++ b/DEPS @@ -98,7 +98,7 @@ hooks = [ 'pattern': '.', 'condition': 'checkout_mac', 'action': ['vpython3', 'build/download_dep.py', - 'omaha4/BraveUpdater-136.1.79.71.zip', + 'omaha4/BraveUpdater-141.1.84.102.zip', '//brave/third_party/updater/mac', 'BraveUpdater.app/'], }, diff --git a/chromium_src/chrome/updater/DEPS b/chromium_src/chrome/updater/DEPS new file mode 100644 index 00000000000..9e807ceb8cf --- /dev/null +++ b/chromium_src/chrome/updater/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+brave/components/update_client/privacy_preserving_protocol_handler.h", +] diff --git a/chromium_src/chrome/updater/configurator.cc b/chromium_src/chrome/updater/configurator.cc new file mode 100644 index 00000000000..41b170484a1 --- /dev/null +++ b/chromium_src/chrome/updater/configurator.cc @@ -0,0 +1,10 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/update_client/privacy_preserving_protocol_handler.h" + +#define ProtocolHandlerFactoryJSON PrivacyPreservingProtocolHandlerFactory +#include +#undef ProtocolHandlerFactoryJSON diff --git a/chromium_src/chrome/updater/ping_configurator.cc b/chromium_src/chrome/updater/ping_configurator.cc new file mode 100644 index 00000000000..f7f971b701a --- /dev/null +++ b/chromium_src/chrome/updater/ping_configurator.cc @@ -0,0 +1,10 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/update_client/privacy_preserving_protocol_handler.h" + +#define ProtocolHandlerFactoryJSON PrivacyPreservingProtocolHandlerFactory +#include +#undef ProtocolHandlerFactoryJSON diff --git a/chromium_src/components/component_updater/DEPS b/chromium_src/components/component_updater/DEPS index 8b94a7c27d5..e00c38bebbe 100644 --- a/chromium_src/components/component_updater/DEPS +++ b/chromium_src/components/component_updater/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+brave/components/update_client/privacy_preserving_protocol_handler.h", "+components/crx_file", "+components/update_client", ] diff --git a/chromium_src/components/component_updater/configurator_impl.cc b/chromium_src/components/component_updater/configurator_impl.cc index 589eeb15eaa..9185c239263 100644 --- a/chromium_src/components/component_updater/configurator_impl.cc +++ b/chromium_src/components/component_updater/configurator_impl.cc @@ -5,9 +5,13 @@ #include "components/component_updater/configurator_impl.h" +#include "brave/components/update_client/privacy_preserving_protocol_handler.h" + #define EnabledBackgroundDownloader EnabledBackgroundDownloader_Unused #define EnabledCupSigning EnabledCupSigning_Unused +#define ProtocolHandlerFactoryJSON PrivacyPreservingProtocolHandlerFactory #include +#undef ProtocolHandlerFactoryJSON #undef EnabledCupSigning #undef EnabledBackgroundDownloader diff --git a/components/BUILD.gn b/components/BUILD.gn index 87635b71ce5..11e9270e8ba 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn @@ -31,9 +31,11 @@ test("brave_components_unittests") { "//brave/components/brave_shields/core/browser:unit_tests", "//brave/components/brave_shields/core/common:unit_tests", "//brave/components/brave_wallet/common:unit_tests", + "//brave/components/component_updater:unit_tests", "//brave/components/email_aliases:unit_tests", "//brave/components/json:unit_tests", "//brave/components/static_redirect_helper:unit_tests", + "//brave/components/update_client:unit_tests", "//components/test:run_all_unittests", ] diff --git a/components/component_updater/BUILD.gn b/components/component_updater/BUILD.gn new file mode 100644 index 00000000000..19f55348239 --- /dev/null +++ b/components/component_updater/BUILD.gn @@ -0,0 +1,16 @@ +# Copyright (c) 2025 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +source_set("unit_tests") { + testonly = true + sources = [ "configurator_impl_unittest.cc" ] + deps = [ + "//base", + "//brave/components/update_client:test_util", + "//components/component_updater", + "//components/update_client", + "//testing/gtest", + ] +} diff --git a/components/component_updater/DEPS b/components/component_updater/DEPS new file mode 100644 index 00000000000..4d52d4588ba --- /dev/null +++ b/components/component_updater/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+components/component_updater", + "+components/update_client", +] diff --git a/components/component_updater/configurator_impl_unittest.cc b/components/component_updater/configurator_impl_unittest.cc new file mode 100644 index 00000000000..910f82c8f2d --- /dev/null +++ b/components/component_updater/configurator_impl_unittest.cc @@ -0,0 +1,30 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "components/component_updater/configurator_impl.h" + +#include "brave/components/update_client/test_util.h" +#include "components/update_client/command_line_config_policy.h" +#include "components/update_client/protocol_handler.h" +#include "components/update_client/protocol_serializer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace component_updater { + +TEST(BraveComponentUpdaterConfiguratorImplTest, + UsesPrivacyPreservingProtocolSerializer) { + auto configurator = std::make_unique( + update_client::CommandLineConfigPolicy(), false); + + auto factory = configurator->GetProtocolHandlerFactory(); + ASSERT_TRUE(factory); + + auto serializer = factory->CreateSerializer(); + ASSERT_TRUE(serializer); + + EXPECT_TRUE(update_client::StripsPrivacySensitiveData(*serializer)); +} + +} // namespace component_updater diff --git a/components/update_client/BUILD.gn b/components/update_client/BUILD.gn index 32cbe1f0a8a..1fd7616a374 100644 --- a/components/update_client/BUILD.gn +++ b/components/update_client/BUILD.gn @@ -22,3 +22,31 @@ buildflag_header("buildflags") { "UPDATER_PROD_ENDPOINT=\"$updater_prod_endpoint\"", ] } + +source_set("unit_tests") { + testonly = true + sources = [ "privacy_preserving_protocol_handler_unittest.cc" ] + deps = [ + ":test_util", + "//components/update_client", + "//testing/gtest", + + # The build fails without this dep, even though our source doesn't use it. + "//base", + ] +} + +source_set("test_util") { + testonly = true + sources = [ + "test_util.cc", + "test_util.h", + ] + deps = [ + "//base", + "//components/prefs", + "//components/prefs:test_support", + "//components/update_client", + "//third_party/re2", + ] +} diff --git a/components/update_client/DEPS b/components/update_client/DEPS new file mode 100644 index 00000000000..69ece58d6d9 --- /dev/null +++ b/components/update_client/DEPS @@ -0,0 +1,10 @@ +include_rules = [ + "+components/update_client", +] +specific_include_rules = { + "test_util.cc": [ + "+components/prefs/pref_service.h", + "+components/prefs/testing_pref_service.h", + "+third_party/re2", + ] +} diff --git a/components/update_client/privacy_preserving_protocol_handler.cc b/components/update_client/privacy_preserving_protocol_handler.cc new file mode 100644 index 00000000000..0d5f20c8a3a --- /dev/null +++ b/components/update_client/privacy_preserving_protocol_handler.cc @@ -0,0 +1,27 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/update_client/privacy_preserving_protocol_handler.h" + +#include + +#include "brave/components/update_client/privacy_preserving_protocol_serializer.h" +#include "components/update_client/protocol_handler.h" +#include "components/update_client/protocol_parser.h" + +namespace update_client { + +std::unique_ptr +PrivacyPreservingProtocolHandlerFactory::CreateParser() const { + // We're not interested in changing this behavior. Mirror upstream. + return ProtocolHandlerFactoryJSON().CreateParser(); +} + +std::unique_ptr +PrivacyPreservingProtocolHandlerFactory::CreateSerializer() const { + return std::make_unique(); +} + +} // namespace update_client diff --git a/components/update_client/privacy_preserving_protocol_handler.h b/components/update_client/privacy_preserving_protocol_handler.h new file mode 100644 index 00000000000..17de83c3ebd --- /dev/null +++ b/components/update_client/privacy_preserving_protocol_handler.h @@ -0,0 +1,29 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UPDATE_CLIENT_PRIVACY_PRESERVING_PROTOCOL_HANDLER_H_ +#define BRAVE_COMPONENTS_UPDATE_CLIENT_PRIVACY_PRESERVING_PROTOCOL_HANDLER_H_ + +#include + +#include "components/update_client/protocol_handler.h" +#include "components/update_client/protocol_parser.h" +#include "components/update_client/protocol_serializer.h" + +namespace update_client { + +// This class returns the same parser as upstream but returns a different +// serializer (PrivacyPreservingProtocolSerializer) to remove values from update +// requests that could be used to fingerprint users. +class PrivacyPreservingProtocolHandlerFactory : public ProtocolHandlerFactory { + public: + // Overrides for ProtocolHandlerFactory. + std::unique_ptr CreateParser() const override; + std::unique_ptr CreateSerializer() const override; +}; + +} // namespace update_client + +#endif // BRAVE_COMPONENTS_UPDATE_CLIENT_PRIVACY_PRESERVING_PROTOCOL_HANDLER_H_ diff --git a/components/update_client/privacy_preserving_protocol_handler_unittest.cc b/components/update_client/privacy_preserving_protocol_handler_unittest.cc new file mode 100644 index 00000000000..b8c494a3bbc --- /dev/null +++ b/components/update_client/privacy_preserving_protocol_handler_unittest.cc @@ -0,0 +1,17 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/update_client/privacy_preserving_protocol_serializer.h" +#include "brave/components/update_client/test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace update_client { + +TEST(PrivacyPreservingProtocolSerializer, StripsPrivacySensitiveData) { + EXPECT_TRUE( + StripsPrivacySensitiveData(PrivacyPreservingProtocolSerializer())); +} + +} // namespace update_client diff --git a/components/update_client/privacy_preserving_protocol_serializer.cc b/components/update_client/privacy_preserving_protocol_serializer.cc new file mode 100644 index 00000000000..3fb36627923 --- /dev/null +++ b/components/update_client/privacy_preserving_protocol_serializer.cc @@ -0,0 +1,65 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/update_client/privacy_preserving_protocol_serializer.h" + +#include +#include + +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/values.h" +#include "components/update_client/protocol_definition.h" +#include "components/update_client/protocol_serializer_json.h" + +namespace update_client { + +// This method returns the same result as upstream's ProtocolSerializerJSON, +// but with some fields removed that could be used to fingerprint users. +std::string PrivacyPreservingProtocolSerializer::Serialize( + const protocol_request::Request& request) const { + std::string upstream_result = ProtocolSerializerJSON().Serialize(request); + std::optional root = base::JSONReader::Read(upstream_result); + if (!root.has_value() || !root->is_dict()) { + return upstream_result; + } + + base::Value::Dict& root_dict = root->GetDict(); + base::Value::Dict* request_dict = root_dict.FindDict("request"); + if (!request_dict) { + return upstream_result; + } + + // We don't want to send the information in the hw dictionary, but the + // protocol specification requires it to be present. All its fields have + // default values and are therefore optional. We therefore remain + // spec-compliant by simply sending an empty hw dictionary. + if (base::Value::Dict* hw_dict = request_dict->FindDict("hw")) { + hw_dict->clear(); + } + + if (base::Value::List* apps = request_dict->FindList("apps")) { + for (auto& app : *apps) { + if (!app.is_dict()) { + continue; + } + + base::Value::Dict& app_dict = app.GetDict(); + app_dict.Remove("lang"); + + if (base::Value::List* events = app_dict.FindList("events")) { + for (auto& event : *events) { + if (event.is_dict()) { + event.GetDict().Remove("download_time_ms"); + } + } + } + } + } + + return base::WriteJson(*root).value_or(std::move(upstream_result)); +} + +} // namespace update_client diff --git a/components/update_client/privacy_preserving_protocol_serializer.h b/components/update_client/privacy_preserving_protocol_serializer.h new file mode 100644 index 00000000000..162b636f50f --- /dev/null +++ b/components/update_client/privacy_preserving_protocol_serializer.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UPDATE_CLIENT_PRIVACY_PRESERVING_PROTOCOL_SERIALIZER_H_ +#define BRAVE_COMPONENTS_UPDATE_CLIENT_PRIVACY_PRESERVING_PROTOCOL_SERIALIZER_H_ + +#include + +#include "components/update_client/protocol_definition.h" +#include "components/update_client/protocol_serializer.h" + +namespace update_client { +// PrivacyPreservingProtocolSerializer wraps around upstream's +// ProtocolSerializerJSON, removing values from update requests that could be +// used to fingerprint users. +class PrivacyPreservingProtocolSerializer : public ProtocolSerializer { + public: + PrivacyPreservingProtocolSerializer() = default; + + PrivacyPreservingProtocolSerializer( + const PrivacyPreservingProtocolSerializer&) = delete; + PrivacyPreservingProtocolSerializer& operator=( + const PrivacyPreservingProtocolSerializer&) = delete; + + // Overrides for ProtocolSerializer. + std::string Serialize( + const protocol_request::Request& request) const override; +}; + +} // namespace update_client + +#endif // BRAVE_COMPONENTS_UPDATE_CLIENT_PRIVACY_PRESERVING_PROTOCOL_SERIALIZER_H_ diff --git a/components/update_client/sources.gni b/components/update_client/sources.gni index ae99b3beab5..cca94e01683 100644 --- a/components/update_client/sources.gni +++ b/components/update_client/sources.gni @@ -3,6 +3,13 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. +brave_components_update_client_sources = [ + "//brave/components/update_client/privacy_preserving_protocol_handler.cc", + "//brave/components/update_client/privacy_preserving_protocol_handler.h", + "//brave/components/update_client/privacy_preserving_protocol_serializer.cc", + "//brave/components/update_client/privacy_preserving_protocol_serializer.h", +] + brave_components_update_client_deps = [ "//brave/components/constants", "//brave/components/widevine:constants", diff --git a/components/update_client/test_util.cc b/components/update_client/test_util.cc new file mode 100644 index 00000000000..71453def608 --- /dev/null +++ b/components/update_client/test_util.cc @@ -0,0 +1,86 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "brave/components/update_client/test_util.h" + +#include +#include +#include +#include + +#include "base/functional/bind.h" +#include "base/values.h" +#include "base/version.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/testing_pref_service.h" +#include "components/update_client/persisted_data.h" +#include "components/update_client/protocol_definition.h" +#include "components/update_client/protocol_serializer.h" +#include "third_party/re2/src/re2/re2.h" + +namespace update_client { + +// This function checks two things. First, that the serializer faithfully +// encodes the necessary data for update requests. Second, that it does not +// encode the following fields, which could be used to fingerprint users: +// - hw[*] +// - apps[*].lang +// - apps[*].events[*].download_time_ms +bool StripsPrivacySensitiveData(const ProtocolSerializer& serializer) { + // Much of this code was copied from protocol_serializer_json_unittest.cc. + auto pref = std::make_unique(); + RegisterPersistedDataPrefs(pref->registry()); + auto metadata = CreatePersistedData( + base::BindRepeating([](PrefService* pref) { return pref; }, pref.get()), + nullptr); + + std::vector events(2); + events[0].Set("download_time_ms", 9965); + events[0].Set("eventresult", 1); + events[1].Set("eventtype", 63); + + std::vector apps; + apps.push_back(MakeProtocolApp( + "id1", base::Version("1.0"), "ap1", "BRND", "ins_id", "lang", -1, + "source1", "location1", {{"attr", "1"}}, "c1", "ch1", "cn1", "test", + {9384}, /*cached_hashes=*/{}, + MakeProtocolUpdateCheck(true, "33.12", true, false), + {{"install", "foobar_install_data_index", ""}}, + MakeProtocolPing("id1", metadata.get(), {}), std::move(events))); + + const auto request = MakeProtocolRequest( + false, "{15160585-8ADE-4D3C-839B-1281A6035D1F}", "prod_id", "1.0", + "channel", "OS", "cacheable", std::nullopt, {{"extra", "params"}}, {}, + std::move(apps)); + + const auto request_str = serializer.Serialize(request); + static constexpr char regex[] = + R"({"request":{"@os":"\w+","@updater":"prod_id",)" + R"("acceptformat":"[^"]+",)" + R"("apps":\[{"ap":"ap1","appid":"id1","attr":"1",)" + R"("brand":"BRND","cohort":"c1","cohorthint":"ch1","cohortname":"cn1",)" + R"("data":\[{"index":"foobar_install_data_index","name":"install"}],)" + R"("disabled":\[{"reason":9384}],"enabled":false,)" + R"("events":\[{"eventresult":1},{"eventtype":63}],)" + R"("iid":"ins_id",)" + R"("installdate":-1,)" + R"("installedby":"location1","installsource":"source1",)" + R"("ping":{[^}]*},)" + R"("release_channel":"test",)" + R"("updatecheck":{"rollback_allowed":true,)" + R"("targetversionprefix":"33.12",)" + R"("updatedisabled":true},"version":"1.0"}],"arch":"\w+","dedup":"cr",)" + R"("dlpref":"cacheable","extra":"params",)" + R"("hw":{},)" + R"("ismachine":false,)" + R"("os":{"arch":"[_,-.\w]+","platform":"OS",)" + R"(("sp":"[\s\w]+",)?"version":"[+-.\w]+"},"prodchannel":"channel",)" + R"("prodversion":"1.0","protocol":"4.0","requestid":"{[-\w]{36}}",)" + R"("sessionid":"{[-\w]{36}}","updaterchannel":"channel",)" + R"("updaterversion":"1.0"(,"wow64":true)?}})"; + return RE2::FullMatch(request_str, regex); +} + +} // namespace update_client diff --git a/components/update_client/test_util.h b/components/update_client/test_util.h new file mode 100644 index 00000000000..2cc19175711 --- /dev/null +++ b/components/update_client/test_util.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#ifndef BRAVE_COMPONENTS_UPDATE_CLIENT_TEST_UTIL_H_ +#define BRAVE_COMPONENTS_UPDATE_CLIENT_TEST_UTIL_H_ + +#include "components/update_client/protocol_serializer.h" + +namespace update_client { + +bool StripsPrivacySensitiveData(const ProtocolSerializer& serializer); + +} // namespace update_client + +#endif // BRAVE_COMPONENTS_UPDATE_CLIENT_TEST_UTIL_H_ diff --git a/patches/components-update_client-BUILD.gn.patch b/patches/components-update_client-BUILD.gn.patch index 87745f85eaf..1d800b93a1a 100644 --- a/patches/components-update_client-BUILD.gn.patch +++ b/patches/components-update_client-BUILD.gn.patch @@ -1,12 +1,12 @@ diff --git a/components/update_client/BUILD.gn b/components/update_client/BUILD.gn -index a0f35874277a25cb7d091dafa54730915962439d..d15b797053c03a1c2d192d12158c2524d09510f7 100644 +index a0f35874277a25cb7d091dafa54730915962439d..fb179a65da5712323ea1df316a5653706db55f1b 100644 --- a/components/update_client/BUILD.gn +++ b/components/update_client/BUILD.gn @@ -199,6 +199,7 @@ static_library("update_client") { "background_downloader_win.h", ] } -+ deps += brave_components_update_client_deps public_deps = brave_components_update_client_public_deps ++ sources += brave_components_update_client_sources deps += brave_components_update_client_deps public_deps = brave_components_update_client_public_deps } if (is_mac) { diff --git a/updater/BUILD.gn b/updater/BUILD.gn new file mode 100644 index 00000000000..841bdf6d181 --- /dev/null +++ b/updater/BUILD.gn @@ -0,0 +1,27 @@ +# Copyright (c) 2025 The Brave Authors. All rights reserved. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at https://mozilla.org/MPL/2.0/. + +import("//testing/test.gni") + +if (is_win || is_mac || is_linux) { + test("brave_updater_unittests") { + testonly = true + sources = [ + "configurator_unittest.cc", + "ping_configurator_unittest.cc", + "run_all_unittests.cc", + ] + deps = [ + "//base", + "//base/test:test_support", + "//brave/components/update_client:test_util", + "//chrome/updater:base", + "//chrome/updater:constants_test", + "//components/prefs:test_support", + "//components/update_client", + "//testing/gtest", + ] + } +} diff --git a/updater/DEPS b/updater/DEPS new file mode 100644 index 00000000000..7637c9b5eaa --- /dev/null +++ b/updater/DEPS @@ -0,0 +1,6 @@ +include_rules = [ + "+brave/components/update_client", + "+chrome/updater", + "+components/prefs", + "+components/update_client", +] diff --git a/updater/configurator_unittest.cc b/updater/configurator_unittest.cc new file mode 100644 index 00000000000..932a0647384 --- /dev/null +++ b/updater/configurator_unittest.cc @@ -0,0 +1,49 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "chrome/updater/configurator.h" + +#include + +#include "base/files/file_path.h" +#include "base/memory/scoped_refptr.h" +#include "base/test/task_environment.h" +#include "brave/components/update_client/test_util.h" +#include "chrome/updater/external_constants.h" +#include "chrome/updater/persisted_data.h" +#include "chrome/updater/prefs_impl.h" +#include "chrome/updater/updater_scope.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" +#include "components/update_client/protocol_handler.h" +#include "components/update_client/protocol_serializer.h" +#include "components/update_client/update_client.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace updater { + +TEST(Configurator, UsesPrivacyPreservingProtocolSerializer) { + base::test::TaskEnvironment task_environment; + + auto pref_service = std::make_unique(); + update_client::RegisterPrefs(pref_service->registry()); + RegisterPersistedDataPrefs(pref_service->registry()); + + auto prefs = base::MakeRefCounted(base::FilePath(), nullptr, + std::move(pref_service)); + auto external_constants = CreateExternalConstants(); + + auto configurator = base::MakeRefCounted( + prefs, external_constants, UpdaterScope::kUser); + auto factory = configurator->GetProtocolHandlerFactory(); + ASSERT_TRUE(factory); + + auto serializer = factory->CreateSerializer(); + ASSERT_TRUE(serializer); + + EXPECT_TRUE(update_client::StripsPrivacySensitiveData(*serializer)); +} + +} // namespace updater diff --git a/updater/ping_configurator_unittest.cc b/updater/ping_configurator_unittest.cc new file mode 100644 index 00000000000..2c59df6000d --- /dev/null +++ b/updater/ping_configurator_unittest.cc @@ -0,0 +1,27 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "chrome/updater/ping_configurator.h" + +#include "brave/components/update_client/test_util.h" +#include "components/update_client/protocol_handler.h" +#include "components/update_client/protocol_serializer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace updater { + +TEST(PingConfigurator, UsesPrivacyPreservingProtocolSerializer) { + auto configurator = CreatePingConfigurator(); + + auto factory = configurator->GetProtocolHandlerFactory(); + ASSERT_TRUE(factory); + + auto serializer = factory->CreateSerializer(); + ASSERT_TRUE(serializer); + + EXPECT_TRUE(update_client::StripsPrivacySensitiveData(*serializer)); +} + +} // namespace updater diff --git a/updater/run_all_unittests.cc b/updater/run_all_unittests.cc new file mode 100644 index 00000000000..7b6d352bddf --- /dev/null +++ b/updater/run_all_unittests.cc @@ -0,0 +1,15 @@ +/* Copyright (c) 2025 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#include "base/functional/bind.h" +#include "base/test/launcher/unit_test_launcher.h" +#include "base/test/test_suite.h" + +int main(int argc, char** argv) { + base::TestSuite test_suite(argc, argv); + return base::LaunchUnitTests( + argc, argv, + base::BindOnce(&base::TestSuite::Run, base::Unretained(&test_suite))); +}