1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/network_anonymization_key.h"
6
7 #include <optional>
8
9 #include "base/test/gtest_util.h"
10 #include "base/test/scoped_feature_list.h"
11 #include "base/unguessable_token.h"
12 #include "base/values.h"
13 #include "net/base/features.h"
14 #include "net/base/schemeful_site.h"
15 #include "network_anonymization_key.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "url/gurl.h"
18 #include "url/url_util.h"
19
20 namespace net {
21
22 class NetworkAnonymizationKeyTest : public testing::Test {
23 protected:
24 const SchemefulSite kTestSiteA = SchemefulSite(GURL("http://a.test/"));
25 const SchemefulSite kTestSiteB = SchemefulSite(GURL("http://b.test/"));
26 const SchemefulSite kDataSite = SchemefulSite(GURL("data:foo"));
27 const base::UnguessableToken kNonce = base::UnguessableToken::Create();
28 };
29
30 class NetworkAnonymizationKeyTestWithNikMode
31 : public NetworkAnonymizationKeyTest,
32 public testing::WithParamInterface<NetworkIsolationKey::Mode> {
33 public:
NetworkAnonymizationKeyTestWithNikMode()34 NetworkAnonymizationKeyTestWithNikMode() {
35 switch (GetParam()) {
36 case net::NetworkIsolationKey::Mode::kFrameSiteEnabled:
37 scoped_feature_list_.InitWithFeatures(
38 {},
39 {net::features::kEnableCrossSiteFlagNetworkIsolationKey,
40 net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey});
41 break;
42
43 case net::NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
44 scoped_feature_list_.InitWithFeatures(
45 {net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey},
46 {
47 net::features::kEnableCrossSiteFlagNetworkIsolationKey,
48 });
49 break;
50
51 case net::NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
52 scoped_feature_list_.InitWithFeatures(
53 {net::features::kEnableCrossSiteFlagNetworkIsolationKey},
54 {net::features::kEnableFrameSiteSharedOpaqueNetworkIsolationKey});
55 break;
56 }
57 }
58
59 private:
60 base::test::ScopedFeatureList scoped_feature_list_;
61 };
62
63 INSTANTIATE_TEST_SUITE_P(
64 Tests,
65 NetworkAnonymizationKeyTestWithNikMode,
66 testing::ValuesIn(
67 {NetworkIsolationKey::Mode::kFrameSiteEnabled,
68 NetworkIsolationKey::Mode::kCrossSiteFlagEnabled,
69 NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled}),
__anonf8dcc9950102(const testing::TestParamInfo<NetworkIsolationKey::Mode>& info) 70 [](const testing::TestParamInfo<NetworkIsolationKey::Mode>& info) {
71 switch (info.param) {
72 case NetworkIsolationKey::Mode::kFrameSiteEnabled:
73 return "FrameSiteEnabled";
74 case NetworkIsolationKey::Mode::kCrossSiteFlagEnabled:
75 return "CrossSiteFlagEnabled";
76 case NetworkIsolationKey::Mode::kFrameSiteWithSharedOpaqueEnabled:
77 return "FrameSiteSharedOpaqueEnabled";
78 }
79 });
80
TEST_P(NetworkAnonymizationKeyTestWithNikMode,CreateFromNetworkIsolationKey)81 TEST_P(NetworkAnonymizationKeyTestWithNikMode, CreateFromNetworkIsolationKey) {
82 SchemefulSite site_a = SchemefulSite(GURL("http://a.test/"));
83 SchemefulSite site_b = SchemefulSite(GURL("http://b.test/"));
84 SchemefulSite opaque = SchemefulSite(url::Origin());
85 base::UnguessableToken nik_nonce = base::UnguessableToken::Create();
86
87 NetworkIsolationKey populated_cross_site_nik(site_a, site_b, nik_nonce);
88 NetworkIsolationKey populated_same_site_nik(site_a, site_a, nik_nonce);
89 NetworkIsolationKey populated_same_site_opaque_nik(opaque, opaque, nik_nonce);
90 NetworkIsolationKey empty_nik;
91
92 NetworkAnonymizationKey nak_from_same_site_nik =
93 NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
94 populated_same_site_nik);
95 NetworkAnonymizationKey nak_from_cross_site_nik =
96 NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
97 populated_cross_site_nik);
98 NetworkAnonymizationKey nak_from_same_site_opaque_nik =
99 NetworkAnonymizationKey::CreateFromNetworkIsolationKey(
100 populated_same_site_opaque_nik);
101 NetworkAnonymizationKey nak_from_empty_nik =
102 NetworkAnonymizationKey::CreateFromNetworkIsolationKey(empty_nik);
103
104 // NAKs created when there is no top frame site on the NIK should create an
105 // empty NAK.
106 EXPECT_TRUE(nak_from_empty_nik.IsEmpty());
107
108 // Top site should be populated correctly.
109 EXPECT_EQ(nak_from_same_site_nik.GetTopFrameSite(), site_a);
110 EXPECT_EQ(nak_from_cross_site_nik.GetTopFrameSite(), site_a);
111 EXPECT_EQ(nak_from_same_site_opaque_nik.GetTopFrameSite(), opaque);
112
113 // Nonce should be populated correctly.
114 EXPECT_EQ(nak_from_same_site_nik.GetNonce(), nik_nonce);
115 EXPECT_EQ(nak_from_cross_site_nik.GetNonce(), nik_nonce);
116 EXPECT_EQ(nak_from_same_site_opaque_nik.GetNonce(), nik_nonce);
117
118 // Is cross site boolean should be populated correctly.
119 EXPECT_TRUE(nak_from_same_site_nik.IsSameSite());
120 EXPECT_TRUE(nak_from_cross_site_nik.IsCrossSite());
121 EXPECT_TRUE(nak_from_same_site_opaque_nik.IsSameSite());
122
123 // Double-keyed + cross site bit NAKs created from different third party
124 // cross site contexts should be the different.
125 EXPECT_FALSE(nak_from_same_site_nik == nak_from_cross_site_nik);
126 }
127
TEST_F(NetworkAnonymizationKeyTest,CreateSameSite)128 TEST_F(NetworkAnonymizationKeyTest, CreateSameSite) {
129 SchemefulSite site = SchemefulSite(GURL("http://a.test/"));
130 SchemefulSite opaque = SchemefulSite(url::Origin());
131 NetworkAnonymizationKey key;
132
133 key = NetworkAnonymizationKey::CreateSameSite(site);
134 EXPECT_EQ(key.GetTopFrameSite(), site);
135 EXPECT_FALSE(key.GetNonce().has_value());
136 EXPECT_TRUE(key.IsSameSite());
137
138 key = NetworkAnonymizationKey::CreateSameSite(opaque);
139 EXPECT_EQ(key.GetTopFrameSite(), opaque);
140 EXPECT_FALSE(key.GetNonce().has_value());
141 EXPECT_TRUE(key.IsSameSite());
142 }
143
TEST_F(NetworkAnonymizationKeyTest,CreateCrossSite)144 TEST_F(NetworkAnonymizationKeyTest, CreateCrossSite) {
145 SchemefulSite site = SchemefulSite(GURL("http://a.test/"));
146 SchemefulSite opaque = SchemefulSite(url::Origin());
147 NetworkAnonymizationKey key;
148
149 key = NetworkAnonymizationKey::CreateCrossSite(site);
150 EXPECT_EQ(key.GetTopFrameSite(), site);
151 EXPECT_FALSE(key.GetNonce().has_value());
152 EXPECT_TRUE(key.IsCrossSite());
153
154 key = NetworkAnonymizationKey::CreateCrossSite(opaque);
155 EXPECT_EQ(key.GetTopFrameSite(), opaque);
156 EXPECT_FALSE(key.GetNonce().has_value());
157 EXPECT_TRUE(key.IsCrossSite());
158 }
159
TEST_F(NetworkAnonymizationKeyTest,CreateFromFrameSite)160 TEST_F(NetworkAnonymizationKeyTest, CreateFromFrameSite) {
161 SchemefulSite site_a = SchemefulSite(GURL("http://a.test/"));
162 SchemefulSite site_b = SchemefulSite(GURL("http://b.test/"));
163 SchemefulSite opaque = SchemefulSite(url::Origin());
164 base::UnguessableToken nonce = base::UnguessableToken::Create();
165
166 NetworkAnonymizationKey nak_from_same_site =
167 NetworkAnonymizationKey::CreateFromFrameSite(site_a, site_a, nonce);
168 NetworkAnonymizationKey nak_from_cross_site =
169 NetworkAnonymizationKey::CreateFromFrameSite(site_a, site_b, nonce);
170 NetworkAnonymizationKey nak_from_same_site_opaque =
171 NetworkAnonymizationKey::CreateFromFrameSite(opaque, opaque, nonce);
172
173 // Top site should be populated correctly.
174 EXPECT_EQ(nak_from_same_site.GetTopFrameSite(), site_a);
175 EXPECT_EQ(nak_from_cross_site.GetTopFrameSite(), site_a);
176 EXPECT_EQ(nak_from_same_site_opaque.GetTopFrameSite(), opaque);
177
178 // Nonce should be populated correctly.
179 EXPECT_EQ(nak_from_same_site.GetNonce(), nonce);
180 EXPECT_EQ(nak_from_cross_site.GetNonce(), nonce);
181 EXPECT_EQ(nak_from_same_site_opaque.GetNonce(), nonce);
182
183 // Is cross site boolean should be populated correctly.
184 EXPECT_TRUE(nak_from_same_site.IsSameSite());
185 EXPECT_TRUE(nak_from_cross_site.IsCrossSite());
186 EXPECT_TRUE(nak_from_same_site_opaque.IsSameSite());
187
188 // Double-keyed + cross site bit NAKs created from different third party
189 // cross site contexts should be the different.
190 EXPECT_FALSE(nak_from_same_site == nak_from_cross_site);
191 }
192
TEST_F(NetworkAnonymizationKeyTest,IsEmpty)193 TEST_F(NetworkAnonymizationKeyTest, IsEmpty) {
194 NetworkAnonymizationKey empty_key;
195 NetworkAnonymizationKey populated_key =
196 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
197 /*is_cross_site=*/false,
198 /*nonce=*/std::nullopt);
199
200 EXPECT_TRUE(empty_key.IsEmpty());
201 EXPECT_FALSE(populated_key.IsEmpty());
202 }
203
TEST_F(NetworkAnonymizationKeyTest,CreateTransient)204 TEST_F(NetworkAnonymizationKeyTest, CreateTransient) {
205 NetworkAnonymizationKey transient_key1 =
206 NetworkAnonymizationKey::CreateTransient();
207 NetworkAnonymizationKey transient_key2 =
208 NetworkAnonymizationKey::CreateTransient();
209
210 EXPECT_TRUE(transient_key1.IsTransient());
211 EXPECT_TRUE(transient_key2.IsTransient());
212 EXPECT_FALSE(transient_key1 == transient_key2);
213 }
214
TEST_F(NetworkAnonymizationKeyTest,IsTransient)215 TEST_F(NetworkAnonymizationKeyTest, IsTransient) {
216 NetworkAnonymizationKey empty_key;
217 NetworkAnonymizationKey populated_key =
218 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
219 /*is_cross_site=*/false,
220 /*nonce=*/std::nullopt);
221 NetworkAnonymizationKey data_top_frame_key =
222 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kDataSite,
223 /*is_cross_site=*/false,
224 /*nonce=*/std::nullopt);
225 NetworkAnonymizationKey populated_key_with_nonce =
226 NetworkAnonymizationKey::CreateFromParts(
227 /*top_frame_site=*/kTestSiteA,
228 /*is_cross_site*/ false, base::UnguessableToken::Create());
229 NetworkAnonymizationKey data_frame_key =
230 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
231 /*is_cross_site=*/false,
232 /*nonce=*/std::nullopt);
233
234 NetworkAnonymizationKey from_create_transient =
235 NetworkAnonymizationKey::CreateTransient();
236
237 EXPECT_TRUE(empty_key.IsTransient());
238 EXPECT_FALSE(populated_key.IsTransient());
239 EXPECT_TRUE(data_top_frame_key.IsTransient());
240 EXPECT_TRUE(populated_key_with_nonce.IsTransient());
241 EXPECT_TRUE(from_create_transient.IsTransient());
242
243 NetworkAnonymizationKey populated_double_key =
244 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
245 /*is_cross_site=*/false,
246 /*nonce=*/std::nullopt);
247 EXPECT_FALSE(data_frame_key.IsTransient());
248 EXPECT_FALSE(populated_double_key.IsTransient());
249 }
250
TEST_F(NetworkAnonymizationKeyTest,IsFullyPopulated)251 TEST_F(NetworkAnonymizationKeyTest, IsFullyPopulated) {
252 NetworkAnonymizationKey empty_key;
253 NetworkAnonymizationKey populated_key =
254 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
255 /*is_cross_site=*/false,
256 /*nonce=*/std::nullopt);
257 EXPECT_TRUE(populated_key.IsFullyPopulated());
258 EXPECT_FALSE(empty_key.IsFullyPopulated());
259 NetworkAnonymizationKey empty_frame_site_key =
260 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
261 /*is_cross_site=*/false,
262 /*nonce=*/std::nullopt);
263 EXPECT_TRUE(empty_frame_site_key.IsFullyPopulated());
264 }
265
TEST_F(NetworkAnonymizationKeyTest,Getters)266 TEST_F(NetworkAnonymizationKeyTest, Getters) {
267 NetworkAnonymizationKey key =
268 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
269 /*is_cross_site=*/true, kNonce);
270
271 EXPECT_EQ(key.GetTopFrameSite(), kTestSiteA);
272 EXPECT_EQ(key.GetNonce(), kNonce);
273
274 EXPECT_TRUE(key.IsCrossSite());
275 }
276
TEST_F(NetworkAnonymizationKeyTest,ToDebugString)277 TEST_F(NetworkAnonymizationKeyTest, ToDebugString) {
278 NetworkAnonymizationKey key =
279 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
280 /*is_cross_site=*/true, kNonce);
281 NetworkAnonymizationKey empty_key;
282
283 // `is_cross_site` holds the value the key is created with.
284 std::string double_key_with_cross_site_flag_expected_string_value =
285 kTestSiteA.GetDebugString() + " cross_site (with nonce " +
286 kNonce.ToString() + ")";
287 EXPECT_EQ(key.ToDebugString(),
288 double_key_with_cross_site_flag_expected_string_value);
289 EXPECT_EQ(empty_key.ToDebugString(), "null");
290 }
291
TEST_F(NetworkAnonymizationKeyTest,Equality)292 TEST_F(NetworkAnonymizationKeyTest, Equality) {
293 NetworkAnonymizationKey key =
294 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
295 /*is_cross_site=*/false, kNonce);
296 NetworkAnonymizationKey key_duplicate =
297 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
298 /*is_cross_site=*/false, kNonce);
299 EXPECT_TRUE(key == key_duplicate);
300 EXPECT_FALSE(key != key_duplicate);
301 EXPECT_FALSE(key < key_duplicate);
302
303 NetworkAnonymizationKey key_cross_site =
304 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
305 /*is_cross_site=*/true, kNonce);
306
307 // The `is_cross_site` flag changes the NAK.
308 EXPECT_FALSE(key == key_cross_site);
309 EXPECT_TRUE(key != key_cross_site);
310 EXPECT_TRUE(key < key_cross_site);
311
312 NetworkAnonymizationKey key_no_nonce =
313 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
314 /*is_cross_site=*/false,
315 /*nonce=*/std::nullopt);
316 EXPECT_FALSE(key == key_no_nonce);
317 EXPECT_TRUE(key != key_no_nonce);
318 EXPECT_FALSE(key < key_no_nonce);
319
320 NetworkAnonymizationKey key_different_nonce =
321 NetworkAnonymizationKey::CreateFromParts(
322 /*top_frame_site=*/kTestSiteA,
323 /*is_cross_site=*/false,
324 /*nonce=*/base::UnguessableToken::Create());
325 EXPECT_FALSE(key == key_different_nonce);
326 EXPECT_TRUE(key != key_different_nonce);
327
328 NetworkAnonymizationKey key_different_frame_site =
329 NetworkAnonymizationKey::CreateFromParts(
330 /*top_frame_site=*/kTestSiteA,
331 /*is_cross_site=*/false, kNonce);
332
333 EXPECT_TRUE(key == key_different_frame_site);
334 EXPECT_FALSE(key != key_different_frame_site);
335 EXPECT_FALSE(key < key_different_frame_site);
336
337 NetworkAnonymizationKey key_different_top_level_site =
338 NetworkAnonymizationKey::CreateFromParts(
339 /*top_frame_site=*/kTestSiteB,
340 /*is_cross_site=*/false, kNonce);
341 EXPECT_FALSE(key == key_different_top_level_site);
342 EXPECT_TRUE(key != key_different_top_level_site);
343 EXPECT_TRUE(key < key_different_top_level_site);
344
345 NetworkAnonymizationKey empty_key;
346 NetworkAnonymizationKey empty_key_duplicate;
347 EXPECT_TRUE(empty_key == empty_key_duplicate);
348 EXPECT_FALSE(empty_key != empty_key_duplicate);
349 EXPECT_FALSE(empty_key < empty_key_duplicate);
350
351 EXPECT_FALSE(empty_key == key);
352 EXPECT_TRUE(empty_key != key);
353 EXPECT_TRUE(empty_key < key);
354 }
355
TEST_F(NetworkAnonymizationKeyTest,ValueRoundTripCrossSite)356 TEST_F(NetworkAnonymizationKeyTest, ValueRoundTripCrossSite) {
357 const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
358 NetworkAnonymizationKey original_key =
359 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
360 /*is_cross_site=*/true);
361 base::Value value;
362 ASSERT_TRUE(original_key.ToValue(&value));
363
364 // Fill initial value with opaque data, to make sure it's overwritten.
365 NetworkAnonymizationKey from_value_key = NetworkAnonymizationKey();
366 EXPECT_TRUE(NetworkAnonymizationKey::FromValue(value, &from_value_key));
367 EXPECT_EQ(original_key, from_value_key);
368 }
369
TEST_F(NetworkAnonymizationKeyTest,ValueRoundTripSameSite)370 TEST_F(NetworkAnonymizationKeyTest, ValueRoundTripSameSite) {
371 const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
372 NetworkAnonymizationKey original_key =
373 NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
374 /*is_cross_site=*/false);
375 base::Value value;
376 ASSERT_TRUE(original_key.ToValue(&value));
377
378 // Fill initial value with opaque data, to make sure it's overwritten.
379 NetworkAnonymizationKey from_value_key = NetworkAnonymizationKey();
380 EXPECT_TRUE(NetworkAnonymizationKey::FromValue(value, &from_value_key));
381 EXPECT_EQ(original_key, from_value_key);
382 }
383
TEST_F(NetworkAnonymizationKeyTest,TransientValueRoundTrip)384 TEST_F(NetworkAnonymizationKeyTest, TransientValueRoundTrip) {
385 const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
386 NetworkAnonymizationKey original_key =
387 NetworkAnonymizationKey::CreateTransient();
388 base::Value value;
389 ASSERT_FALSE(original_key.ToValue(&value));
390 }
391
TEST_F(NetworkAnonymizationKeyTest,EmptyValueRoundTrip)392 TEST_F(NetworkAnonymizationKeyTest, EmptyValueRoundTrip) {
393 const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
394 NetworkAnonymizationKey original_key;
395 base::Value value;
396 ASSERT_TRUE(original_key.ToValue(&value));
397
398 // Fill initial value with opaque data, to make sure it's overwritten.
399 NetworkAnonymizationKey from_value_key = NetworkAnonymizationKey();
400 EXPECT_TRUE(NetworkAnonymizationKey::FromValue(value, &from_value_key));
401 EXPECT_EQ(original_key, from_value_key);
402 }
403
TEST(NetworkAnonymizationKeyFeatureShiftTest,ValueRoundTripKeySchemeMissmatch)404 TEST(NetworkAnonymizationKeyFeatureShiftTest,
405 ValueRoundTripKeySchemeMissmatch) {
406 base::test::ScopedFeatureList scoped_feature_list_;
407 const SchemefulSite kOpaqueSite = SchemefulSite(GURL("data:text/html,junk"));
408 const SchemefulSite kTestSiteA = SchemefulSite(GURL("http://a.test/"));
409 const SchemefulSite kTestSiteB = SchemefulSite(GURL("http://b.test/"));
410 NetworkAnonymizationKey expected_failure_nak = NetworkAnonymizationKey();
411
412 // Create a cross site double key + cross site flag NetworkAnonymizationKey.
413 NetworkAnonymizationKey original_cross_site_double_key =
414 NetworkAnonymizationKey::CreateFromParts(kTestSiteA, false);
415 base::Value cross_site_double_key_value;
416 ASSERT_TRUE(
417 original_cross_site_double_key.ToValue(&cross_site_double_key_value));
418
419 // Check that deserializing a double keyed NetworkAnonymizationKey (a
420 // one-element list) fails, using the serialized site from
421 // `cross_site_double_key_value` to build it.
422 base::Value serialized_site =
423 cross_site_double_key_value.GetList()[0].Clone();
424 base::Value::List double_key_list;
425 double_key_list.Append(serialized_site.Clone());
426 base::Value double_key_value = base::Value(std::move(double_key_list));
427 EXPECT_FALSE(NetworkAnonymizationKey::FromValue(double_key_value,
428 &expected_failure_nak));
429
430 // Check that deserializing a triple keyed value (a 2-element list
431 // containing two sites) fails.
432 base::Value::List triple_key_list;
433 triple_key_list.Append(serialized_site.Clone());
434 triple_key_list.Append(std::move(serialized_site));
435 base::Value triple_key_value = base::Value(std::move(triple_key_list));
436 EXPECT_FALSE(NetworkAnonymizationKey::FromValue(triple_key_value,
437 &expected_failure_nak));
438
439 // Convert the successful value back to a NAK and verify.
440 NetworkAnonymizationKey from_value_cross_site_double_key =
441 NetworkAnonymizationKey();
442 EXPECT_TRUE(NetworkAnonymizationKey::FromValue(
443 cross_site_double_key_value, &from_value_cross_site_double_key));
444 EXPECT_EQ(original_cross_site_double_key, from_value_cross_site_double_key);
445 }
446
447 } // namespace net
448