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