Skip to content

Commit f946678

Browse files
committed
Clamp platform version client hint.
1 parent c690eb4 commit f946678

File tree

9 files changed

+187
-10
lines changed

9 files changed

+187
-10
lines changed

browser/about_flags.cc

+8
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,14 @@
390390
kOsAll, \
391391
FEATURE_VALUE_TYPE(blink::features::kAllowCertainClientHints), \
392392
}, \
393+
{ \
394+
"clamp-platform-version-client-hint", \
395+
"Clamp platform version client hint", \
396+
"Clamps the patch field of the platform version client hint", \
397+
kOsAll, \
398+
FEATURE_VALUE_TYPE( \
399+
blink::features::kClampPlatformVersionClientHint), \
400+
}, \
393401
{ \
394402
"brave-ntp-branded-wallpaper-demo", \
395403
"New Tab Page Demo Branded Wallpaper", \

browser/test/disabled_features/disable_client_hints_browsertest.cc

+56-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "base/functional/bind.h"
1313
#include "base/path_service.h"
1414
#include "base/run_loop.h"
15+
#include "base/strings/strcat.h"
1516
#include "base/strings/string_util.h"
1617
#include "base/test/scoped_feature_list.h"
1718
#include "brave/components/constants/brave_paths.h"
@@ -36,6 +37,8 @@ const char KClientHintsMetaHTTPEquivAcceptCH[] =
3637
"/ch-meta-http-equiv-accept-ch.html";
3738
const char KClientHintsMetaNameAcceptCH[] = "/ch-meta-name-accept-ch.html";
3839

40+
const char kPlatformVersionClientHintPatchValue[] = "x";
41+
3942
const std::reference_wrapper<const base::Feature> kTestFeatures[] = {
4043
// Individual hints features
4144
blink::features::kClientHintsDeviceMemory,
@@ -93,23 +96,30 @@ class ClientHintsBrowserTest
9396

9497
void SetUp() override {
9598
// Test that even with CH features enabled, there is no header.
96-
std::vector<base::test::FeatureRef> enabled_features;
99+
std::vector<base::test::FeatureRefAndParams> enabled_features;
97100
std::vector<base::test::FeatureRef> disabled_features;
98101
for (const auto& feature : kTestFeatures) {
99102
if (IsClientHintHeaderEnabled()) {
100-
enabled_features.push_back(feature.get());
103+
enabled_features.emplace_back(feature.get(), base::FieldTrialParams());
101104
} else {
102105
disabled_features.push_back(feature.get());
103106
}
104107
}
105108

106109
if (IsBraveClientHintFeatureEnabled()) {
107-
enabled_features.push_back(blink::features::kAllowCertainClientHints);
110+
enabled_features.emplace_back(blink::features::kAllowCertainClientHints,
111+
base::FieldTrialParams());
112+
base::FieldTrialParams parameters;
113+
parameters[blink::features::kClampPlatformVersionClientHintPatchValue
114+
.name] = kPlatformVersionClientHintPatchValue;
115+
enabled_features.emplace_back(
116+
blink::features::kClampPlatformVersionClientHint, parameters);
108117
} else {
109118
disabled_features.push_back(blink::features::kAllowCertainClientHints);
110119
}
111120

112-
scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
121+
scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features,
122+
disabled_features);
113123

114124
if (IsBraveClientHintFeatureEnabled()) {
115125
PopulateDefaultClientHints();
@@ -154,28 +164,39 @@ class ClientHintsBrowserTest
154164
return unexpected_client_hints_headers_seen_.size();
155165
}
156166

157-
std::string default_client_hints_headers_seen() {
167+
std::string default_client_hints_headers_seen() const {
158168
return base::JoinString(
159169
std::vector<std::string>(default_client_hints_headers_seen_.begin(),
160170
default_client_hints_headers_seen_.end()),
161171
", ");
162172
}
163173

164-
std::string allowed_client_hints_headers_seen() {
174+
std::string allowed_client_hints_headers_seen() const {
165175
return base::JoinString(
166176
std::vector<std::string>(allowed_client_hints_headers_seen_.begin(),
167177
allowed_client_hints_headers_seen_.end()),
168178
", ");
169179
}
170180

171-
std::string unexpected_client_hints_headers_seen() {
181+
std::string unexpected_client_hints_headers_seen() const {
172182
return base::JoinString(unexpected_client_hints_headers_seen_, ", ");
173183
}
174184

185+
std::string platform_version_client_hint_value() const {
186+
return platform_version_client_hint_value_;
187+
}
188+
175189
void reset_client_hints_headers_seen() {
176190
default_client_hints_headers_seen_.clear();
177191
allowed_client_hints_headers_seen_.clear();
178192
unexpected_client_hints_headers_seen_.clear();
193+
platform_version_client_hint_value_ = "";
194+
}
195+
196+
bool VerifyPlatformVersionClientHintPatchValue() const {
197+
return base::EndsWith(
198+
platform_version_client_hint_value_,
199+
base::StrCat({".", kPlatformVersionClientHintPatchValue, "\""}));
179200
}
180201

181202
private:
@@ -197,6 +218,21 @@ class ClientHintsBrowserTest
197218
hints_map.at(network::mojom::WebClientHintsType::kUAPlatformVersion));
198219
}
199220

221+
bool IsPlatformVersionClientHintHeader(const std::string& header) const {
222+
return header ==
223+
network::GetClientHintToNameMap().at(
224+
network::mojom::WebClientHintsType::kUAPlatformVersion);
225+
}
226+
227+
void StorePlatformVersionClientHintHeaderValue(
228+
const net::test_server::HttpRequest::HeaderMap& headers) {
229+
const auto& hints_map = network::GetClientHintToNameMap();
230+
const std::string& platform_version_header_name =
231+
hints_map.at(network::mojom::WebClientHintsType::kUAPlatformVersion);
232+
platform_version_client_hint_value_ =
233+
headers.at(platform_version_header_name);
234+
}
235+
200236
void MonitorResourceRequest(const net::test_server::HttpRequest& request) {
201237
for (const auto& elem : network::GetClientHintToNameMap()) {
202238
const auto& header = elem.second;
@@ -207,6 +243,9 @@ class ClientHintsBrowserTest
207243
continue;
208244
} else if (base::Contains(allowed_hints_, header)) {
209245
allowed_client_hints_headers_seen_.insert(header);
246+
if (IsPlatformVersionClientHintHeader(header)) {
247+
StorePlatformVersionClientHintHeaderValue(request.headers);
248+
}
210249
continue;
211250
}
212251
}
@@ -230,10 +269,12 @@ class ClientHintsBrowserTest
230269
std::vector<std::string> default_hints_;
231270
std::vector<std::string> allowed_hints_;
232271

272+
std::string platform_version_client_hint_value_;
273+
233274
base::test::ScopedFeatureList scoped_feature_list_;
234275
};
235276

236-
IN_PROC_BROWSER_TEST_P(ClientHintsBrowserTest, ClientHintsDisabled) {
277+
IN_PROC_BROWSER_TEST_P(ClientHintsBrowserTest, CheckClientHints) {
237278
for (const auto& feature : kTestFeatures) {
238279
EXPECT_EQ(IsClientHintHeaderEnabled(),
239280
base::FeatureList::IsEnabled(feature));
@@ -269,6 +310,13 @@ IN_PROC_BROWSER_TEST_P(ClientHintsBrowserTest, ClientHintsDisabled) {
269310
<< "Allowed headers seen: " << allowed_client_hints_headers_seen();
270311
EXPECT_EQ(0u, client_hints_headers_seen_count())
271312
<< "Unexpected headers: " << unexpected_client_hints_headers_seen();
313+
if (IsClientHintHeaderEnabled() && IsBraveClientHintFeatureEnabled()) {
314+
EXPECT_TRUE(VerifyPlatformVersionClientHintPatchValue())
315+
<< "Expected the patch field value to be: '"
316+
<< kPlatformVersionClientHintPatchValue << "'. "
317+
<< "Actual platform version value: "
318+
<< platform_version_client_hint_value();
319+
}
272320

273321
reset_client_hints_headers_seen();
274322
ASSERT_TRUE(ui_test_utils::NavigateToURL(

chromium_src/components/embedder_support/user_agent_utils.cc

+36
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
44
* You can obtain one at http://mozilla.org/MPL/2.0/. */
55

6+
#include "components/embedder_support/user_agent_utils.h"
7+
8+
#include "base/check_op.h"
9+
#include "base/strings/stringprintf.h"
10+
#include "base/version.h"
11+
#include "third_party/blink/public/common/features.h"
12+
613
namespace {
714

815
constexpr char kBraveBrandNameForCHUA[] = "Brave";
@@ -18,5 +25,34 @@ constexpr char kBraveBrandNameForCHUA[] = "Brave";
1825
// can't use it here in the //components.
1926
#define BRAVE_GET_USER_AGENT_BRAND_LIST brand = kBraveBrandNameForCHUA;
2027

28+
#define GetUserAgentMetadata GetUserAgentMetadata_ChromiumImpl
2129
#include "src/components/embedder_support/user_agent_utils.cc"
30+
#undef GetUserAgentMetadata
2231
#undef BRAVE_GET_USER_AGENT_BRAND_LIST
32+
33+
namespace embedder_support {
34+
35+
blink::UserAgentMetadata GetUserAgentMetadata() {
36+
return GetUserAgentMetadata(nullptr);
37+
}
38+
39+
blink::UserAgentMetadata GetUserAgentMetadata(const PrefService* pref_service) {
40+
blink::UserAgentMetadata metadata =
41+
GetUserAgentMetadata_ChromiumImpl(pref_service);
42+
if (base::FeatureList::IsEnabled(
43+
blink::features::kClampPlatformVersionClientHint)) {
44+
// Clamp platform version
45+
base::Version platform_version(metadata.platform_version);
46+
// Expect Chromium code to return `major.minor.patch` version. If that
47+
// changes we need to re-evaluate what we want to send.
48+
CHECK_EQ(3u, platform_version.components().size());
49+
metadata.platform_version = base::StringPrintf(
50+
"%d.%d.%s", platform_version.components()[0],
51+
platform_version.components()[1],
52+
blink::features::kClampPlatformVersionClientHintPatchValue.Get()
53+
.c_str());
54+
}
55+
return metadata;
56+
}
57+
58+
} // namespace embedder_support
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* Copyright (c) 2023 The Brave Authors. All rights reserved.
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
4+
* You can obtain one at https://mozilla.org/MPL/2.0/. */
5+
6+
#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_EMBEDDER_SUPPORT_USER_AGENT_UTILS_H_
7+
#define BRAVE_CHROMIUM_SRC_COMPONENTS_EMBEDDER_SUPPORT_USER_AGENT_UTILS_H_
8+
9+
#define GetUserAgentMetadata GetUserAgentMetadata_ChromiumImpl
10+
#include "src/components/embedder_support/user_agent_utils.h" // IWYU pragma: export
11+
#undef GetUserAgentMetadata
12+
13+
namespace embedder_support {
14+
15+
blink::UserAgentMetadata GetUserAgentMetadata();
16+
17+
blink::UserAgentMetadata GetUserAgentMetadata(const PrefService* pref_service);
18+
19+
} // namespace embedder_support
20+
21+
#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_EMBEDDER_SUPPORT_USER_AGENT_UTILS_H_

chromium_src/third_party/blink/common/client_hints/enabled_client_hints.cc

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
// Additionally, if we receive CH requests for
1818
// kUAPlatformVersion and/or kUAModel, we will send these, but:
1919
// - kUAModel will be always set to an empty string;
20-
// - kUAPlatformVersion will be clamped to the same value we report in the
21-
// User-Agent string.
20+
// - kUAPlatformVersion will have a clamped patch field value.
2221

2322
namespace blink {
2423

chromium_src/third_party/blink/common/features.cc

+11
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ BASE_FEATURE(kAllowCertainClientHints,
5151
"AllowCertainClientHints",
5252
base::FEATURE_DISABLED_BY_DEFAULT);
5353

54+
// Clamp platform version client hint's patch field.
55+
// Platform version client hint is only sent when requested and when the
56+
// AllowCertainClientHints feature is turned on.
57+
BASE_FEATURE(kClampPlatformVersionClientHint,
58+
"ClampPlatformVersionClientHint",
59+
base::FEATURE_ENABLED_BY_DEFAULT);
60+
61+
constexpr base::FeatureParam<std::string>
62+
kClampPlatformVersionClientHintPatchValue{&kClampPlatformVersionClientHint,
63+
"patch_value", "0"};
64+
5465
BASE_FEATURE(kFileSystemAccessAPI,
5566
"FileSystemAccessAPI",
5667
base::FEATURE_DISABLED_BY_DEFAULT);

chromium_src/third_party/blink/public/common/features.h

+8
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88

99
#include "src/third_party/blink/public/common/features.h" // IWYU pragma: export
1010

11+
#include <string>
12+
1113
namespace blink {
1214
namespace features {
1315

1416
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kAllowCertainClientHints);
17+
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kClampPlatformVersionClientHint);
1518
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kFileSystemAccessAPI);
1619
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kNavigatorConnectionAttribute);
1720
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kPartitionBlinkMemoryCache);
@@ -20,6 +23,11 @@ BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kBraveBlockScreenFingerprinting);
2023
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kBraveRoundTimeStamps);
2124
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kRestrictEventSourcePool);
2225

26+
// Specifies the value of the third component of the dotted version of the
27+
// platform version client hint.
28+
BLINK_COMMON_EXPORT extern const base::FeatureParam<std::string>
29+
kClampPlatformVersionClientHintPatchValue;
30+
2331
// Chromium used this function to control Prerender2 feature, but then the
2432
// feature was permanently enabled and the function was removed. We still want
2533
// to keep the Prerender2 functionality disabled, so putting back the function

components/embedder_support/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ source_set("unit_tests") {
1111
sources = [ "user_agent_utils_unittest.cc" ]
1212

1313
deps = [
14+
"//base/test:test_support",
1415
"//components/embedder_support:browser_util",
1516
"//components/version_info",
1617
"//testing/gtest",

components/embedder_support/user_agent_utils_unittest.cc

+45
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
* You can obtain one at http://mozilla.org/MPL/2.0/. */
55

66
#include "components/embedder_support/user_agent_utils.h"
7+
#include "base/strings/string_number_conversions.h"
8+
#include "base/test/scoped_feature_list.h"
9+
#include "base/version.h"
710
#include "components/version_info/version_info.h"
811
#include "testing/gtest/include/gtest/gtest.h"
12+
#include "third_party/blink/public/common/features.h"
913
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
1014

1115
namespace embedder_support {
@@ -33,4 +37,45 @@ TEST(UserAgentUtilsTest, UserAgentMetadata) {
3337
ContainsBrandVersion(metadata.brand_version_list, product_brand_version));
3438
}
3539

40+
TEST(UserAgentUtilsTest, DoNotClampPlatformVersion) {
41+
base::test::ScopedFeatureList feature_list;
42+
feature_list.InitWithFeatures(
43+
{blink::features::kAllowCertainClientHints},
44+
{blink::features::kClampPlatformVersionClientHint});
45+
auto metadata = GetUserAgentMetadata_ChromiumImpl();
46+
auto brave_metadata = GetUserAgentMetadata(nullptr);
47+
EXPECT_EQ(metadata, brave_metadata);
48+
}
49+
50+
TEST(UserAgentUtilsTest, ClampPlatformVersion) {
51+
static const char kClampedValue[] = "7775777";
52+
base::test::ScopedFeatureList feature_list;
53+
std::vector<base::test::FeatureRefAndParams> enabled_features;
54+
enabled_features.emplace_back(blink::features::kAllowCertainClientHints,
55+
base::FieldTrialParams());
56+
base::FieldTrialParams parameters;
57+
parameters[blink::features::kClampPlatformVersionClientHintPatchValue.name] =
58+
kClampedValue;
59+
enabled_features.emplace_back(
60+
blink::features::kClampPlatformVersionClientHint, parameters);
61+
feature_list.InitWithFeaturesAndParameters(enabled_features, {});
62+
63+
auto metadata = GetUserAgentMetadata_ChromiumImpl();
64+
auto brave_metadata = GetUserAgentMetadata(nullptr);
65+
66+
base::Version platform_version(metadata.platform_version);
67+
base::Version brave_platform_version(brave_metadata.platform_version);
68+
69+
EXPECT_EQ(3u, platform_version.components().size());
70+
EXPECT_EQ(3u, brave_platform_version.components().size());
71+
EXPECT_EQ(platform_version.components()[0],
72+
brave_platform_version.components()[0]);
73+
EXPECT_EQ(platform_version.components()[1],
74+
brave_platform_version.components()[1]);
75+
EXPECT_NE(platform_version.components()[2],
76+
brave_platform_version.components()[2]);
77+
EXPECT_EQ(kClampedValue,
78+
base::NumberToString(brave_platform_version.components()[2]));
79+
}
80+
3681
} // namespace embedder_support

0 commit comments

Comments
 (0)