Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 1 | // Copyright 2019 The Chromium Authors. All rights reserved. |
| 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_isolation_key.h" |
| 6 | |
Matt Menke | 166443c | 2019-05-24 18:45:59 | [diff] [blame] | 7 | #include "base/stl_util.h" |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 8 | #include "base/test/scoped_feature_list.h" |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 9 | #include "base/values.h" |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 10 | #include "net/base/features.h" |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 11 | #include "testing/gtest/include/gtest/gtest.h" |
| 12 | #include "url/gurl.h" |
| 13 | #include "url/origin.h" |
| 14 | |
| 15 | namespace net { |
| 16 | |
| 17 | TEST(NetworkIsolationKeyTest, EmptyKey) { |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 18 | base::test::ScopedFeatureList feature_list; |
| 19 | feature_list.InitAndDisableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 20 | features::kAppendFrameOriginToNetworkIsolationKey); |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 21 | |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 22 | NetworkIsolationKey key; |
| 23 | EXPECT_FALSE(key.IsFullyPopulated()); |
| 24 | EXPECT_EQ(std::string(), key.ToString()); |
| 25 | EXPECT_TRUE(key.IsTransient()); |
Matt Menke | 166443c | 2019-05-24 18:45:59 | [diff] [blame] | 26 | EXPECT_EQ("null", key.ToDebugString()); |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 27 | } |
| 28 | |
| 29 | TEST(NetworkIsolationKeyTest, NonEmptyKey) { |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 30 | base::test::ScopedFeatureList feature_list; |
| 31 | feature_list.InitAndDisableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 32 | features::kAppendFrameOriginToNetworkIsolationKey); |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 33 | |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 34 | url::Origin origin = url::Origin::Create(GURL("http://a.test/")); |
Shivani Sharma | 8ae506c | 2019-07-21 21:08:27 | [diff] [blame] | 35 | NetworkIsolationKey key(origin, origin); |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 36 | EXPECT_TRUE(key.IsFullyPopulated()); |
| 37 | EXPECT_EQ(origin.Serialize(), key.ToString()); |
| 38 | EXPECT_FALSE(key.IsTransient()); |
Matt Menke | 166443c | 2019-05-24 18:45:59 | [diff] [blame] | 39 | EXPECT_EQ("http://a.test", key.ToDebugString()); |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | TEST(NetworkIsolationKeyTest, OpaqueOriginKey) { |
| 43 | url::Origin origin_data = |
| 44 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); |
Shivani Sharma | 8ae506c | 2019-07-21 21:08:27 | [diff] [blame] | 45 | NetworkIsolationKey key(origin_data, origin_data); |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 46 | EXPECT_TRUE(key.IsFullyPopulated()); |
| 47 | EXPECT_EQ(std::string(), key.ToString()); |
| 48 | EXPECT_TRUE(key.IsTransient()); |
Matt Menke | 166443c | 2019-05-24 18:45:59 | [diff] [blame] | 49 | |
| 50 | // Create another opaque origin, and make sure it has a different debug |
| 51 | // string. |
Shivani Sharma | 8ae506c | 2019-07-21 21:08:27 | [diff] [blame] | 52 | const auto kOriginNew = origin_data.DeriveNewOpaqueOrigin(); |
| 53 | EXPECT_NE(key.ToDebugString(), |
| 54 | NetworkIsolationKey(kOriginNew, kOriginNew).ToDebugString()); |
Matt Menke | 166443c | 2019-05-24 18:45:59 | [diff] [blame] | 55 | } |
| 56 | |
| 57 | TEST(NetworkIsolationKeyTest, Operators) { |
| 58 | // These are in ascending order. |
| 59 | const NetworkIsolationKey kKeys[] = { |
| 60 | NetworkIsolationKey(), |
| 61 | // Unique origins are still sorted by scheme, so data is before file, and |
| 62 | // file before http. |
| 63 | NetworkIsolationKey( |
Shivani Sharma | 8ae506c | 2019-07-21 21:08:27 | [diff] [blame] | 64 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")), |
Matt Menke | 166443c | 2019-05-24 18:45:59 | [diff] [blame] | 65 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>"))), |
Shivani Sharma | 8ae506c | 2019-07-21 21:08:27 | [diff] [blame] | 66 | NetworkIsolationKey(url::Origin::Create(GURL("file:///foo")), |
| 67 | url::Origin::Create(GURL("file:///foo"))), |
| 68 | NetworkIsolationKey(url::Origin::Create(GURL("http://a.test/")), |
| 69 | url::Origin::Create(GURL("http://a.test/"))), |
| 70 | NetworkIsolationKey(url::Origin::Create(GURL("http://b.test/")), |
| 71 | url::Origin::Create(GURL("http://b.test/"))), |
| 72 | NetworkIsolationKey(url::Origin::Create(GURL("https://a.test/")), |
| 73 | url::Origin::Create(GURL("https://a.test/"))), |
Matt Menke | 166443c | 2019-05-24 18:45:59 | [diff] [blame] | 74 | }; |
| 75 | |
| 76 | for (size_t first = 0; first < base::size(kKeys); ++first) { |
| 77 | NetworkIsolationKey key1 = kKeys[first]; |
| 78 | SCOPED_TRACE(key1.ToDebugString()); |
| 79 | |
| 80 | EXPECT_TRUE(key1 == key1); |
| 81 | EXPECT_FALSE(key1 < key1); |
| 82 | |
| 83 | // Make sure that copying a key doesn't change the results of any operation. |
| 84 | // This check is a bit more interesting with unique origins. |
| 85 | NetworkIsolationKey key1_copy = key1; |
| 86 | EXPECT_TRUE(key1 == key1_copy); |
| 87 | EXPECT_FALSE(key1 < key1_copy); |
| 88 | EXPECT_FALSE(key1_copy < key1); |
| 89 | |
| 90 | for (size_t second = first + 1; second < base::size(kKeys); ++second) { |
| 91 | NetworkIsolationKey key2 = kKeys[second]; |
| 92 | SCOPED_TRACE(key2.ToDebugString()); |
| 93 | |
| 94 | EXPECT_TRUE(key1 < key2); |
| 95 | EXPECT_FALSE(key2 < key1); |
| 96 | EXPECT_FALSE(key1 == key2); |
| 97 | EXPECT_FALSE(key2 == key1); |
| 98 | } |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | TEST(NetworkIsolationKeyTest, UniqueOriginOperators) { |
Shivani Sharma | 8ae506c | 2019-07-21 21:08:27 | [diff] [blame] | 103 | const auto kOrigin1 = |
| 104 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); |
| 105 | const auto kOrigin2 = |
| 106 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); |
| 107 | NetworkIsolationKey key1(kOrigin1, kOrigin1); |
| 108 | NetworkIsolationKey key2(kOrigin2, kOrigin2); |
Matt Menke | 166443c | 2019-05-24 18:45:59 | [diff] [blame] | 109 | |
| 110 | EXPECT_TRUE(key1 == key1); |
| 111 | EXPECT_TRUE(key2 == key2); |
| 112 | |
| 113 | // Creating copies shouldn't affect comparison result. |
| 114 | EXPECT_TRUE(NetworkIsolationKey(key1) == NetworkIsolationKey(key1)); |
| 115 | EXPECT_TRUE(NetworkIsolationKey(key2) == NetworkIsolationKey(key2)); |
| 116 | |
| 117 | EXPECT_FALSE(key1 == key2); |
| 118 | EXPECT_FALSE(key2 == key1); |
| 119 | |
| 120 | // Order of Nonces isn't predictable, but they should have an ordering. |
| 121 | EXPECT_TRUE(key1 < key2 || key2 < key1); |
| 122 | EXPECT_TRUE(!(key1 < key2) || !(key2 < key1)); |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 123 | } |
| 124 | |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 125 | TEST(NetworkIsolationKeyTest, KeyWithOpaqueFrameOrigin) { |
| 126 | base::test::ScopedFeatureList feature_list; |
| 127 | feature_list.InitAndDisableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 128 | features::kAppendFrameOriginToNetworkIsolationKey); |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 129 | |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 130 | url::Origin origin_data = |
| 131 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); |
| 132 | |
| 133 | NetworkIsolationKey key1(url::Origin::Create(GURL("http://a.test")), |
| 134 | origin_data); |
| 135 | EXPECT_TRUE(key1.IsFullyPopulated()); |
| 136 | EXPECT_FALSE(key1.IsTransient()); |
| 137 | EXPECT_EQ("http://a.test", key1.ToString()); |
| 138 | EXPECT_EQ("http://a.test", key1.ToDebugString()); |
| 139 | |
| 140 | NetworkIsolationKey key2(origin_data, |
| 141 | url::Origin::Create(GURL("http://a.test"))); |
| 142 | EXPECT_TRUE(key2.IsFullyPopulated()); |
| 143 | EXPECT_TRUE(key2.IsTransient()); |
| 144 | EXPECT_EQ("", key2.ToString()); |
| 145 | EXPECT_EQ(origin_data.GetDebugString(), key2.ToDebugString()); |
| 146 | EXPECT_NE(origin_data.DeriveNewOpaqueOrigin().GetDebugString(), |
| 147 | key2.ToDebugString()); |
| 148 | } |
| 149 | |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 150 | TEST(NetworkIsolationKeyTest, ValueRoundTripEmpty) { |
| 151 | const url::Origin kJunkOrigin = |
| 152 | url::Origin::Create(GURL("data:text/html,junk")); |
| 153 | |
| 154 | // Convert empty key to value and back, expecting the same value. |
| 155 | NetworkIsolationKey no_frame_origin_key; |
| 156 | base::Value no_frame_origin_value; |
| 157 | ASSERT_TRUE(no_frame_origin_key.ToValue(&no_frame_origin_value)); |
| 158 | |
| 159 | // Fill initial value with junk data, to make sure it's overwritten. |
| 160 | NetworkIsolationKey out_key(kJunkOrigin, kJunkOrigin); |
| 161 | EXPECT_TRUE(NetworkIsolationKey::FromValue(no_frame_origin_value, &out_key)); |
| 162 | EXPECT_EQ(no_frame_origin_key, out_key); |
| 163 | |
| 164 | // Perform same checks when frame origins are enabled. |
| 165 | |
| 166 | base::test::ScopedFeatureList feature_list; |
| 167 | feature_list.InitAndEnableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 168 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 169 | |
| 170 | NetworkIsolationKey frame_origin_key; |
| 171 | base::Value frame_origin_value; |
| 172 | ASSERT_TRUE(frame_origin_key.ToValue(&frame_origin_value)); |
| 173 | |
| 174 | // Fill initial value with junk data, to make sure it's overwritten. |
| 175 | out_key = NetworkIsolationKey(kJunkOrigin, kJunkOrigin); |
| 176 | EXPECT_TRUE(NetworkIsolationKey::FromValue(frame_origin_value, &out_key)); |
| 177 | EXPECT_EQ(frame_origin_key, out_key); |
| 178 | |
| 179 | // The Values should also be the same in both cases. |
| 180 | EXPECT_EQ(no_frame_origin_key, frame_origin_key); |
| 181 | } |
| 182 | |
| 183 | TEST(NetworkIsolationKeyTest, ValueRoundTripNoFrameOrigin) { |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 184 | base::test::ScopedFeatureList feature_list; |
| 185 | feature_list.InitAndDisableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 186 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 187 | const url::Origin kJunkOrigin = |
| 188 | url::Origin::Create(GURL("data:text/html,junk")); |
| 189 | |
| 190 | NetworkIsolationKey key1(url::Origin::Create(GURL("https://foo.test/")), |
| 191 | kJunkOrigin); |
| 192 | base::Value value; |
| 193 | ASSERT_TRUE(key1.ToValue(&value)); |
| 194 | |
| 195 | // Fill initial value with junk data, to make sure it's overwritten. |
| 196 | NetworkIsolationKey key2(kJunkOrigin, kJunkOrigin); |
| 197 | EXPECT_TRUE(NetworkIsolationKey::FromValue(value, &key2)); |
| 198 | EXPECT_EQ(key1, key2); |
| 199 | |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 200 | feature_list.Reset(); |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 201 | feature_list.InitAndEnableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 202 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 203 | |
| 204 | // Loading should fail when frame origins are enabled. |
| 205 | EXPECT_FALSE(NetworkIsolationKey::FromValue(value, &key2)); |
| 206 | } |
| 207 | |
| 208 | TEST(NetworkIsolationKeyTest, ValueRoundTripFrameOrigin) { |
| 209 | const url::Origin kJunkOrigin = |
| 210 | url::Origin::Create(GURL("data:text/html,junk")); |
| 211 | |
| 212 | base::test::ScopedFeatureList feature_list; |
| 213 | feature_list.InitAndEnableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 214 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 215 | |
| 216 | NetworkIsolationKey key1(url::Origin::Create(GURL("https://foo.test/")), |
| 217 | url::Origin::Create(GURL("https://foo.test/"))); |
| 218 | base::Value value; |
| 219 | ASSERT_TRUE(key1.ToValue(&value)); |
| 220 | |
| 221 | // Fill initial value with junk data, to make sure it's overwritten. |
| 222 | NetworkIsolationKey key2(kJunkOrigin, kJunkOrigin); |
| 223 | EXPECT_TRUE(NetworkIsolationKey::FromValue(value, &key2)); |
| 224 | EXPECT_EQ(key1, key2); |
| 225 | |
| 226 | feature_list.Reset(); |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 227 | feature_list.InitAndDisableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 228 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 229 | |
| 230 | // Loading should fail when frame origins are disabled. |
| 231 | EXPECT_FALSE(NetworkIsolationKey::FromValue(value, &key2)); |
| 232 | } |
| 233 | |
| 234 | TEST(NetworkIsolationKeyTest, ToValueTransientOrigin) { |
| 235 | const url::Origin kTransientOrigin = |
| 236 | url::Origin::Create(GURL("data:text/html,transient")); |
| 237 | |
| 238 | for (bool use_frame_origins : {false, true}) { |
| 239 | SCOPED_TRACE(use_frame_origins); |
| 240 | base::test::ScopedFeatureList feature_list; |
| 241 | if (use_frame_origins) { |
| 242 | feature_list.InitAndEnableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 243 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 244 | } |
| 245 | |
| 246 | NetworkIsolationKey key1(kTransientOrigin, kTransientOrigin); |
| 247 | EXPECT_TRUE(key1.IsTransient()); |
| 248 | base::Value value; |
| 249 | EXPECT_FALSE(key1.ToValue(&value)); |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | TEST(NetworkIsolationKeyTest, FromValueBadData) { |
| 254 | // Can't create these inline, since vector initialization lists require a |
| 255 | // copy, and base::Value has no copy operator, only move. |
| 256 | base::Value::ListStorage not_a_url_list; |
| 257 | not_a_url_list.emplace_back(base::Value("not-a-url")); |
| 258 | |
| 259 | base::Value::ListStorage transient_origin_list; |
| 260 | transient_origin_list.emplace_back(base::Value("data:text/html,transient")); |
| 261 | |
| 262 | base::Value::ListStorage too_many_origins_list; |
| 263 | too_many_origins_list.emplace_back(base::Value("https://too/")); |
| 264 | too_many_origins_list.emplace_back(base::Value("https://many/")); |
| 265 | too_many_origins_list.emplace_back(base::Value("https://origins/")); |
| 266 | |
| 267 | const base::Value kTestCases[] = { |
| 268 | base::Value(base::Value::Type::STRING), |
| 269 | base::Value(base::Value::Type::DICTIONARY), |
| 270 | base::Value(std::move(not_a_url_list)), |
| 271 | base::Value(std::move(transient_origin_list)), |
| 272 | base::Value(std::move(too_many_origins_list)), |
| 273 | }; |
| 274 | |
| 275 | for (bool use_frame_origins : {false, true}) { |
| 276 | SCOPED_TRACE(use_frame_origins); |
| 277 | base::test::ScopedFeatureList feature_list; |
| 278 | if (use_frame_origins) { |
| 279 | feature_list.InitAndEnableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 280 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | 2fa4599 | 2019-08-06 23:07:35 | [diff] [blame] | 281 | } |
| 282 | |
| 283 | for (const auto& test_case : kTestCases) { |
| 284 | NetworkIsolationKey key; |
| 285 | // Write the value on failure. |
| 286 | EXPECT_FALSE(NetworkIsolationKey::FromValue(test_case, &key)) |
| 287 | << test_case; |
| 288 | } |
| 289 | } |
| 290 | } |
| 291 | |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 292 | TEST(NetworkIsolationKeyTest, UseRegistrableDomain) { |
| 293 | base::test::ScopedFeatureList feature_list; |
Shivani Sharma | aa302034 | 2019-11-20 20:56:57 | [diff] [blame] | 294 | feature_list.InitWithFeatures( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 295 | {features::kUseRegistrableDomainInNetworkIsolationKey}, |
| 296 | {features::kAppendFrameOriginToNetworkIsolationKey}); |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 297 | |
| 298 | // Both origins are non-opaque. |
| 299 | url::Origin origin_a = url::Origin::Create(GURL("http://a.foo.test:80")); |
| 300 | url::Origin origin_b = url::Origin::Create(GURL("https://b.foo.test:2395")); |
| 301 | |
| 302 | // Resultant NIK should have the same scheme as the initial origin and |
| 303 | // default port. Note that frame_origin will be empty as triple keying is not |
| 304 | // enabled. |
| 305 | url::Origin expected_domain_a = url::Origin::Create(GURL("http://foo.test")); |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 306 | NetworkIsolationKey key(origin_a, origin_b); |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 307 | EXPECT_EQ(origin_a, key.GetTopFrameOrigin().value()); |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 308 | EXPECT_FALSE(key.GetFrameOrigin().has_value()); |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 309 | EXPECT_EQ(expected_domain_a.Serialize(), key.ToString()); |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 310 | |
| 311 | // More tests for using registrable domain are in |
| 312 | // NetworkIsolationKeyWithFrameOriginTest.UseRegistrableDomain. |
| 313 | } |
| 314 | |
Yao Xiao | 6924a36a | 2019-07-12 16:55:19 | [diff] [blame] | 315 | class NetworkIsolationKeyWithFrameOriginTest : public testing::Test { |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 316 | public: |
Yao Xiao | 6924a36a | 2019-07-12 16:55:19 | [diff] [blame] | 317 | NetworkIsolationKeyWithFrameOriginTest() { |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 318 | feature_list_.InitAndEnableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 319 | features::kAppendFrameOriginToNetworkIsolationKey); |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 320 | } |
| 321 | |
| 322 | private: |
| 323 | base::test::ScopedFeatureList feature_list_; |
| 324 | }; |
| 325 | |
Yao Xiao | 6924a36a | 2019-07-12 16:55:19 | [diff] [blame] | 326 | TEST_F(NetworkIsolationKeyWithFrameOriginTest, WithFrameOrigin) { |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 327 | NetworkIsolationKey key(url::Origin::Create(GURL("http://b.test")), |
| 328 | url::Origin::Create(GURL("http://a.test/"))); |
| 329 | EXPECT_TRUE(key.IsFullyPopulated()); |
| 330 | EXPECT_FALSE(key.IsTransient()); |
| 331 | EXPECT_EQ("http://b.test http://a.test", key.ToString()); |
| 332 | EXPECT_EQ("http://b.test http://a.test", key.ToDebugString()); |
| 333 | |
| 334 | EXPECT_TRUE(key == key); |
| 335 | EXPECT_FALSE(key != key); |
| 336 | EXPECT_FALSE(key < key); |
| 337 | } |
| 338 | |
Yao Xiao | 6924a36a | 2019-07-12 16:55:19 | [diff] [blame] | 339 | TEST_F(NetworkIsolationKeyWithFrameOriginTest, OpaqueOriginKey) { |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 340 | url::Origin origin_data = |
| 341 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); |
| 342 | |
| 343 | NetworkIsolationKey key1(url::Origin::Create(GURL("http://a.test")), |
| 344 | origin_data); |
| 345 | EXPECT_TRUE(key1.IsFullyPopulated()); |
| 346 | EXPECT_TRUE(key1.IsTransient()); |
| 347 | EXPECT_EQ("", key1.ToString()); |
| 348 | EXPECT_EQ("http://a.test " + origin_data.GetDebugString(), |
| 349 | key1.ToDebugString()); |
| 350 | EXPECT_NE( |
| 351 | "http://a.test " + origin_data.DeriveNewOpaqueOrigin().GetDebugString(), |
| 352 | key1.ToDebugString()); |
| 353 | |
| 354 | NetworkIsolationKey key2(origin_data, |
| 355 | url::Origin::Create(GURL("http://a.test"))); |
| 356 | EXPECT_TRUE(key2.IsFullyPopulated()); |
| 357 | EXPECT_TRUE(key2.IsTransient()); |
| 358 | EXPECT_EQ("", key2.ToString()); |
| 359 | EXPECT_EQ(origin_data.GetDebugString() + " http://a.test", |
| 360 | key2.ToDebugString()); |
| 361 | EXPECT_NE( |
| 362 | origin_data.DeriveNewOpaqueOrigin().GetDebugString() + " http://a.test", |
| 363 | key2.ToDebugString()); |
| 364 | } |
| 365 | |
Yao Xiao | 6924a36a | 2019-07-12 16:55:19 | [diff] [blame] | 366 | TEST_F(NetworkIsolationKeyWithFrameOriginTest, OpaqueOriginKeyBoth) { |
Eric Robinson | fc7de10 | 2019-06-21 15:27:10 | [diff] [blame] | 367 | url::Origin origin_data_1 = |
| 368 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); |
| 369 | url::Origin origin_data_2 = |
| 370 | url::Origin::Create(GURL("data:text/html,<body>Hello Universe</body>")); |
| 371 | url::Origin origin_data_3 = |
| 372 | url::Origin::Create(GURL("data:text/html,<body>Hello Cosmos</body>")); |
| 373 | |
| 374 | NetworkIsolationKey key1(origin_data_1, origin_data_2); |
| 375 | NetworkIsolationKey key2(origin_data_1, origin_data_2); |
| 376 | NetworkIsolationKey key3(origin_data_1, origin_data_3); |
| 377 | |
| 378 | // All the keys should be fully populated and transient. |
| 379 | EXPECT_TRUE(key1.IsFullyPopulated()); |
| 380 | EXPECT_TRUE(key2.IsFullyPopulated()); |
| 381 | EXPECT_TRUE(key3.IsFullyPopulated()); |
| 382 | EXPECT_TRUE(key1.IsTransient()); |
| 383 | EXPECT_TRUE(key2.IsTransient()); |
| 384 | EXPECT_TRUE(key3.IsTransient()); |
| 385 | |
| 386 | // Test the equality/comparisons of the various keys |
| 387 | EXPECT_TRUE(key1 == key2); |
| 388 | EXPECT_FALSE(key1 == key3); |
| 389 | EXPECT_FALSE(key1 < key2 || key2 < key1); |
| 390 | EXPECT_TRUE(key1 < key3 || key3 < key1); |
| 391 | |
| 392 | // Test the ToString and ToDebugString |
| 393 | EXPECT_EQ(key1.ToDebugString(), key2.ToDebugString()); |
| 394 | EXPECT_NE(key1.ToDebugString(), key3.ToDebugString()); |
| 395 | EXPECT_EQ("", key1.ToString()); |
| 396 | EXPECT_EQ("", key2.ToString()); |
| 397 | EXPECT_EQ("", key3.ToString()); |
| 398 | } |
| 399 | |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 400 | TEST_F(NetworkIsolationKeyWithFrameOriginTest, UseRegistrableDomain) { |
| 401 | base::test::ScopedFeatureList feature_list; |
| 402 | feature_list.InitWithFeatures( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 403 | {features::kAppendFrameOriginToNetworkIsolationKey, |
| 404 | features::kUseRegistrableDomainInNetworkIsolationKey}, |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 405 | {}); |
| 406 | |
| 407 | // Both origins are non-opaque. |
| 408 | url::Origin origin_a = url::Origin::Create(GURL("http://a.foo.test:80")); |
| 409 | url::Origin origin_b = url::Origin::Create(GURL("https://b.foo.test:2395")); |
| 410 | |
| 411 | // Resultant NIK should have the same schemes as the initial origins and |
| 412 | // default port. |
| 413 | url::Origin expected_domain_a = url::Origin::Create(GURL("http://foo.test")); |
| 414 | url::Origin expected_domain_b = url::Origin::Create(GURL("https://foo.test")); |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 415 | NetworkIsolationKey key(origin_a, origin_b); |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 416 | EXPECT_EQ(origin_a, key.GetTopFrameOrigin().value()); |
| 417 | EXPECT_EQ(origin_b, key.GetFrameOrigin().value()); |
| 418 | EXPECT_EQ(expected_domain_a.Serialize() + " " + expected_domain_b.Serialize(), |
| 419 | key.ToString()); |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 420 | |
| 421 | // Top frame origin is opaque but not the frame origin. |
| 422 | url::Origin origin_data = |
| 423 | url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); |
| 424 | key = NetworkIsolationKey(origin_data, origin_b); |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 425 | EXPECT_TRUE(key.top_frame_origin_->opaque()); |
| 426 | EXPECT_TRUE(key.ToString().empty()); |
| 427 | EXPECT_EQ(origin_data, key.top_frame_origin_.value()); |
| 428 | EXPECT_EQ(expected_domain_b, key.frame_origin_.value()); |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 429 | |
| 430 | // Top frame origin is non-opaque but frame origin is opaque. |
| 431 | key = NetworkIsolationKey(origin_a, origin_data); |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 432 | EXPECT_EQ(expected_domain_a, key.top_frame_origin_.value()); |
| 433 | EXPECT_TRUE(key.ToString().empty()); |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 434 | EXPECT_EQ(origin_data, key.GetFrameOrigin().value()); |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 435 | EXPECT_TRUE(key.frame_origin_->opaque()); |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 436 | |
| 437 | // Empty NIK stays empty. |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 438 | NetworkIsolationKey empty_key; |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 439 | EXPECT_TRUE(key.ToString().empty()); |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 440 | |
| 441 | // IPv4 and IPv6 origins should not be modified, except for removing their |
| 442 | // ports. |
| 443 | url::Origin origin_ipv4 = url::Origin::Create(GURL("http://127.0.0.1:1234")); |
| 444 | url::Origin origin_ipv6 = url::Origin::Create(GURL("https://[::1]")); |
| 445 | key = NetworkIsolationKey(origin_ipv4, origin_ipv6); |
| 446 | EXPECT_EQ(url::Origin::Create(GURL("http://127.0.0.1")), |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 447 | key.top_frame_origin_.value()); |
| 448 | EXPECT_EQ(origin_ipv6, key.frame_origin_.value()); |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 449 | |
| 450 | // Nor should TLDs, recognized or not. |
| 451 | url::Origin origin_tld = url::Origin::Create(GURL("http://com")); |
| 452 | url::Origin origin_tld_unknown = |
| 453 | url::Origin::Create(GURL("https://bar:1234")); |
| 454 | key = NetworkIsolationKey(origin_tld, origin_tld_unknown); |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 455 | EXPECT_EQ(origin_tld, key.top_frame_origin_.value()); |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 456 | EXPECT_EQ(url::Origin::Create(GURL("https://bar")), |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 457 | key.frame_origin_.value()); |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 458 | |
| 459 | // Check for two-part TLDs. |
| 460 | url::Origin origin_two_part_tld = url::Origin::Create(GURL("http://co.uk")); |
| 461 | url::Origin origin_two_part_tld_with_prefix = |
| 462 | url::Origin::Create(GURL("https://a.b.co.uk")); |
| 463 | key = |
| 464 | NetworkIsolationKey(origin_two_part_tld, origin_two_part_tld_with_prefix); |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 465 | EXPECT_EQ(origin_two_part_tld, key.top_frame_origin_.value()); |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 466 | EXPECT_EQ(url::Origin::Create(GURL("https://b.co.uk")), |
Shivani Sharma | 4ee2c2c | 2019-12-17 17:53:38 | [diff] [blame^] | 467 | key.frame_origin_.value()); |
| 468 | |
| 469 | // Two keys with different origins but same etld+1. |
| 470 | // Also test the getter APIs. |
| 471 | url::Origin origin_a_foo = url::Origin::Create(GURL("http://a.foo.com")); |
| 472 | url::Origin foo = url::Origin::Create(GURL("http://foo.com")); |
| 473 | url::Origin origin_b_foo = url::Origin::Create(GURL("http://b.foo.com")); |
| 474 | NetworkIsolationKey key1 = NetworkIsolationKey(origin_a_foo, origin_a_foo); |
| 475 | NetworkIsolationKey key2 = NetworkIsolationKey(origin_b_foo, origin_b_foo); |
| 476 | EXPECT_EQ(key1, key2); |
| 477 | EXPECT_EQ(foo.Serialize() + " " + foo.Serialize(), key1.ToString()); |
| 478 | EXPECT_EQ(foo.Serialize() + " " + foo.Serialize(), key2.ToString()); |
| 479 | EXPECT_EQ(origin_a_foo, key1.GetTopFrameOrigin()); |
| 480 | EXPECT_EQ(origin_a_foo, key1.GetFrameOrigin()); |
| 481 | EXPECT_EQ(origin_b_foo, key2.GetTopFrameOrigin()); |
| 482 | EXPECT_EQ(origin_b_foo, key2.GetFrameOrigin()); |
| 483 | |
| 484 | // Copying one key to another should also copy the original origins. |
| 485 | url::Origin origin_bar = url::Origin::Create(GURL("http://a.bar.com")); |
| 486 | NetworkIsolationKey key_bar = NetworkIsolationKey(origin_bar, origin_bar); |
| 487 | NetworkIsolationKey key_copied = key_bar; |
| 488 | EXPECT_EQ(key_copied.GetTopFrameOrigin(), key_bar.GetTopFrameOrigin()); |
| 489 | EXPECT_EQ(key_copied.GetFrameOrigin(), key_bar.GetFrameOrigin()); |
| 490 | EXPECT_EQ(key_copied, key_bar); |
Shivani Sharma | 53b39d4c | 2019-11-14 11:38:41 | [diff] [blame] | 491 | } |
| 492 | |
Shivani Sharma | 38b74f5 | 2019-12-05 20:16:23 | [diff] [blame] | 493 | TEST_F(NetworkIsolationKeyWithFrameOriginTest, CreateWithNewFrameOrigin) { |
| 494 | url::Origin origin_a = url::Origin::Create(GURL("http://a.com")); |
| 495 | url::Origin origin_b = url::Origin::Create(GURL("http://b.com")); |
| 496 | url::Origin origin_c = url::Origin::Create(GURL("http://c.com")); |
| 497 | |
| 498 | net::NetworkIsolationKey key(origin_a, origin_b); |
| 499 | NetworkIsolationKey key_c = key.CreateWithNewFrameOrigin(origin_c); |
| 500 | EXPECT_EQ(origin_c, key_c.GetFrameOrigin()); |
| 501 | EXPECT_EQ(origin_a, key_c.GetTopFrameOrigin()); |
| 502 | } |
| 503 | |
Matt Menke | f146103d | 2019-11-19 18:21:27 | [diff] [blame] | 504 | TEST(NetworkIsolationKeyTest, CreateTransient) { |
| 505 | for (bool append_frame_origin : {false, true}) { |
| 506 | base::test::ScopedFeatureList feature_list; |
| 507 | if (append_frame_origin) { |
| 508 | feature_list.InitAndEnableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 509 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | f146103d | 2019-11-19 18:21:27 | [diff] [blame] | 510 | } else { |
| 511 | feature_list.InitAndDisableFeature( |
Matt Menke | 4f5cce9 | 2019-12-04 19:23:36 | [diff] [blame] | 512 | features::kAppendFrameOriginToNetworkIsolationKey); |
Matt Menke | f146103d | 2019-11-19 18:21:27 | [diff] [blame] | 513 | } |
| 514 | |
| 515 | NetworkIsolationKey transient_key = NetworkIsolationKey::CreateTransient(); |
| 516 | EXPECT_TRUE(transient_key.IsFullyPopulated()); |
| 517 | EXPECT_TRUE(transient_key.IsTransient()); |
| 518 | EXPECT_FALSE(transient_key.IsEmpty()); |
| 519 | EXPECT_EQ(transient_key, transient_key); |
| 520 | |
| 521 | // Transient values can't be saved to disk. |
| 522 | base::Value value; |
| 523 | EXPECT_FALSE(transient_key.ToValue(&value)); |
| 524 | |
| 525 | // Make sure that subsequent calls don't return the same NIK. |
| 526 | for (int i = 0; i < 1000; ++i) { |
| 527 | EXPECT_NE(transient_key, NetworkIsolationKey::CreateTransient()); |
| 528 | } |
| 529 | } |
| 530 | } |
| 531 | |
Shivani Sharma | d81bdd4 | 2019-05-23 17:19:56 | [diff] [blame] | 532 | } // namespace net |