site_for_cookies_unittest.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  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. #include "net/cookies/site_for_cookies.h"
  5. #include <string>
  6. #include <vector>
  7. #include "base/strings/strcat.h"
  8. #include "base/test/scoped_feature_list.h"
  9. #include "net/base/features.h"
  10. #include "net/base/url_util.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. #include "url/gurl.h"
  13. #include "url/origin.h"
  14. #include "url/url_util.h"
  15. namespace net {
  16. namespace {
  17. class SchemelessSiteForCookiesTest : public ::testing::Test {
  18. public:
  19. SchemelessSiteForCookiesTest() {
  20. scope_feature_list_.InitAndDisableFeature(features::kSchemefulSameSite);
  21. }
  22. protected:
  23. base::test::ScopedFeatureList scope_feature_list_;
  24. };
  25. std::string NormalizedScheme(const GURL& url) {
  26. return url.SchemeIsWSOrWSS() ? ChangeWebSocketSchemeToHttpScheme(url).scheme()
  27. : url.scheme();
  28. }
  29. // Tests that all URLs from |equivalent| produce SiteForCookies that match
  30. // URLs in the set and are equivalent to each other, and are distinct and
  31. // don't match |distinct|.
  32. void TestEquivalentAndDistinct(const std::vector<GURL>& equivalent,
  33. const std::vector<GURL>& distinct,
  34. const std::string& expect_host) {
  35. for (const GURL& equiv_url_a : equivalent) {
  36. SiteForCookies equiv_a = SiteForCookies::FromUrl(equiv_url_a);
  37. EXPECT_EQ(NormalizedScheme(equiv_url_a), equiv_a.scheme());
  38. EXPECT_EQ(equiv_a.RepresentativeUrl().spec(),
  39. base::StrCat({equiv_a.scheme(), "://", expect_host, "/"}));
  40. for (const GURL& equiv_url_b : equivalent) {
  41. SiteForCookies equiv_b = SiteForCookies::FromUrl(equiv_url_a);
  42. EXPECT_TRUE(equiv_a.IsEquivalent(equiv_b));
  43. EXPECT_TRUE(equiv_b.IsEquivalent(equiv_a));
  44. EXPECT_TRUE(equiv_a.IsFirstParty(equiv_url_a));
  45. EXPECT_TRUE(equiv_a.IsFirstParty(equiv_url_b));
  46. EXPECT_TRUE(equiv_b.IsFirstParty(equiv_url_a));
  47. EXPECT_TRUE(equiv_b.IsFirstParty(equiv_url_b));
  48. }
  49. for (const GURL& other_url : distinct) {
  50. SiteForCookies other = SiteForCookies::FromUrl(other_url);
  51. EXPECT_EQ(NormalizedScheme(other_url), other.scheme());
  52. EXPECT_EQ(other.RepresentativeUrl().spec(),
  53. base::StrCat({other.scheme(), "://", other_url.host(), "/"}));
  54. EXPECT_FALSE(equiv_a.IsEquivalent(other));
  55. EXPECT_FALSE(other.IsEquivalent(equiv_a));
  56. EXPECT_FALSE(equiv_a.IsFirstParty(other_url))
  57. << equiv_a.ToDebugString() << " " << other_url.spec();
  58. EXPECT_FALSE(other.IsFirstParty(equiv_url_a));
  59. EXPECT_TRUE(other.IsFirstParty(other_url));
  60. }
  61. }
  62. }
  63. TEST(SiteForCookiesTest, Default) {
  64. SiteForCookies should_match_none;
  65. EXPECT_FALSE(should_match_none.IsFirstParty(GURL("http://example.com")));
  66. EXPECT_FALSE(should_match_none.IsFirstParty(GURL("file:///home/me/.bashrc")));
  67. EXPECT_FALSE(should_match_none.IsFirstParty(GURL::EmptyGURL()));
  68. // Before SiteForCookies existed, empty URL would represent match-none
  69. EXPECT_TRUE(should_match_none.IsEquivalent(
  70. SiteForCookies::FromUrl(GURL::EmptyGURL())));
  71. EXPECT_TRUE(should_match_none.RepresentativeUrl().is_empty());
  72. EXPECT_TRUE(should_match_none.IsEquivalent(
  73. SiteForCookies::FromOrigin(url::Origin())));
  74. EXPECT_TRUE(should_match_none.site().opaque());
  75. EXPECT_EQ("", should_match_none.scheme());
  76. EXPECT_EQ("SiteForCookies: {site=null; schemefully_same=false}",
  77. should_match_none.ToDebugString());
  78. }
  79. TEST_F(SchemelessSiteForCookiesTest, Basic) {
  80. std::vector<GURL> equivalent = {
  81. GURL("https://example.com"),
  82. GURL("http://sub1.example.com:42/something"),
  83. GURL("ws://sub2.example.com/something"),
  84. // This one is disputable.
  85. GURL("file://example.com/helo"),
  86. };
  87. std::vector<GURL> distinct = {GURL("https://example.org"),
  88. GURL("http://com/i_am_a_tld")};
  89. TestEquivalentAndDistinct(equivalent, distinct, "example.com");
  90. }
  91. // Similar to SchemelessSiteForCookiesTest_Basic with a focus on testing secure
  92. // SFCs.
  93. TEST(SiteForCookiesTest, BasicSecure) {
  94. std::vector<GURL> equivalent = {GURL("https://example.com"),
  95. GURL("wss://example.com"),
  96. GURL("https://sub1.example.com:42/something"),
  97. GURL("wss://sub2.example.com/something")};
  98. std::vector<GURL> distinct = {
  99. GURL("http://example.com"), GURL("https://example.org"),
  100. GURL("ws://example.com"), GURL("https://com/i_am_a_tld"),
  101. GURL("file://example.com/helo"),
  102. };
  103. TestEquivalentAndDistinct(equivalent, distinct, "example.com");
  104. }
  105. // Similar to SchemelessSiteForCookiesTest_Basic with a focus on testing
  106. // insecure SFCs.
  107. TEST(SiteForCookiesTest, BasicInsecure) {
  108. std::vector<GURL> equivalent = {GURL("http://example.com"),
  109. GURL("ws://example.com"),
  110. GURL("http://sub1.example.com:42/something"),
  111. GURL("ws://sub2.example.com/something")};
  112. std::vector<GURL> distinct = {
  113. GURL("https://example.com"), GURL("http://example.org"),
  114. GURL("wss://example.com"), GURL("http://com/i_am_a_tld"),
  115. GURL("file://example.com/helo"),
  116. };
  117. TestEquivalentAndDistinct(equivalent, distinct, "example.com");
  118. }
  119. TEST(SiteForCookiesTest, File) {
  120. std::vector<GURL> equivalent = {GURL("file:///a/b/c"),
  121. GURL("file:///etc/shaaadow")};
  122. std::vector<GURL> distinct = {GURL("file://nonlocal/file.txt")};
  123. TestEquivalentAndDistinct(equivalent, distinct, "");
  124. }
  125. TEST_F(SchemelessSiteForCookiesTest, Extension) {
  126. url::ScopedSchemeRegistryForTests scoped_registry;
  127. url::AddStandardScheme("chrome-extension", url::SCHEME_WITH_HOST);
  128. std::vector<GURL> equivalent = {GURL("chrome-extension://abc/"),
  129. GURL("chrome-extension://abc/foo.txt"),
  130. GURL("https://abc"), GURL("http://abc"),
  131. // This one is disputable.
  132. GURL("file://abc/bar.txt")};
  133. std::vector<GURL> distinct = {GURL("chrome-extension://def")};
  134. TestEquivalentAndDistinct(equivalent, distinct, "abc");
  135. }
  136. // Similar to SchemelessSiteForCookiesTest_Extension with a focus on ensuring
  137. // that http(s) schemes are distinct.
  138. TEST(SiteForCookiesTest, Extension) {
  139. url::ScopedSchemeRegistryForTests scoped_registry;
  140. url::AddStandardScheme("chrome-extension", url::SCHEME_WITH_HOST);
  141. std::vector<GURL> equivalent = {
  142. GURL("chrome-extension://abc/"),
  143. GURL("chrome-extension://abc/foo.txt"),
  144. };
  145. std::vector<GURL> distinct = {GURL("chrome-extension://def"),
  146. GURL("https://abc"), GURL("http://abc"),
  147. GURL("file://abc/bar.txt")};
  148. TestEquivalentAndDistinct(equivalent, distinct, "abc");
  149. }
  150. TEST(SiteForCookiesTest, NonStandard) {
  151. // If we don't register the scheme, nothing matches, even identical ones
  152. std::vector<GURL> equivalent;
  153. std::vector<GURL> distinct = {GURL("non-standard://abc"),
  154. GURL("non-standard://abc"),
  155. GURL("non-standard://def")};
  156. // Last parameter is "" since GURL doesn't put the hostname in if
  157. // the URL is non-standard.
  158. TestEquivalentAndDistinct(equivalent, distinct, "");
  159. }
  160. TEST_F(SchemelessSiteForCookiesTest, Blob) {
  161. // This case isn't really well-specified and is inconsistent between
  162. // different user agents; the behavior chosen here was to be more
  163. // consistent between url and origin handling.
  164. //
  165. // Thanks file API spec for the sample blob URL.
  166. SiteForCookies from_blob = SiteForCookies::FromUrl(
  167. GURL("blob:https://example.org/9115d58c-bcda-ff47-86e5-083e9a2153041"));
  168. EXPECT_TRUE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
  169. EXPECT_EQ("https", from_blob.scheme());
  170. EXPECT_EQ("SiteForCookies: {site=https://example.org; schemefully_same=true}",
  171. from_blob.ToDebugString());
  172. EXPECT_EQ("https://example.org/", from_blob.RepresentativeUrl().spec());
  173. EXPECT_TRUE(from_blob.IsEquivalent(
  174. SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
  175. }
  176. // Similar to SchemelessSiteForCookiesTest_Blob with a focus on a secure blob.
  177. TEST(SiteForCookiesTest, SecureBlob) {
  178. SiteForCookies from_blob = SiteForCookies::FromUrl(
  179. GURL("blob:https://example.org/9115d58c-bcda-ff47-86e5-083e9a2153041"));
  180. EXPECT_TRUE(from_blob.IsFirstParty(GURL("https://sub.example.org/resource")));
  181. EXPECT_FALSE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
  182. EXPECT_EQ("https", from_blob.scheme());
  183. EXPECT_EQ("SiteForCookies: {site=https://example.org; schemefully_same=true}",
  184. from_blob.ToDebugString());
  185. EXPECT_EQ("https://example.org/", from_blob.RepresentativeUrl().spec());
  186. EXPECT_TRUE(from_blob.IsEquivalent(
  187. SiteForCookies::FromUrl(GURL("https://www.example.org:631"))));
  188. EXPECT_FALSE(from_blob.IsEquivalent(
  189. SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
  190. }
  191. // Similar to SchemelessSiteForCookiesTest_Blob with a focus on an insecure
  192. // blob.
  193. TEST(SiteForCookiesTest, InsecureBlob) {
  194. SiteForCookies from_blob = SiteForCookies::FromUrl(
  195. GURL("blob:http://example.org/9115d58c-bcda-ff47-86e5-083e9a2153041"));
  196. EXPECT_TRUE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
  197. EXPECT_FALSE(
  198. from_blob.IsFirstParty(GURL("https://sub.example.org/resource")));
  199. EXPECT_EQ("http", from_blob.scheme());
  200. EXPECT_EQ("SiteForCookies: {site=http://example.org; schemefully_same=true}",
  201. from_blob.ToDebugString());
  202. EXPECT_EQ("http://example.org/", from_blob.RepresentativeUrl().spec());
  203. EXPECT_TRUE(from_blob.IsEquivalent(
  204. SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
  205. EXPECT_FALSE(from_blob.IsEquivalent(
  206. SiteForCookies::FromUrl(GURL("https://www.example.org:631"))));
  207. }
  208. TEST_F(SchemelessSiteForCookiesTest, Wire) {
  209. SiteForCookies out;
  210. // Empty one.
  211. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(), false, &out));
  212. EXPECT_TRUE(out.IsNull());
  213. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(), true, &out));
  214. EXPECT_TRUE(out.IsNull());
  215. // Not a valid site. (Scheme should have been converted to https.)
  216. EXPECT_FALSE(SiteForCookies::FromWire(
  217. SchemefulSite(GURL("wss://host.example.test")), false, &out));
  218. EXPECT_TRUE(out.IsNull());
  219. // Not a valid scheme. (Same result as opaque SchemefulSite.)
  220. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("aH://example.test")),
  221. false, &out));
  222. EXPECT_TRUE(out.IsNull());
  223. // Not a eTLD + 1 (or something hosty), but this is fine. (Is converted to a
  224. // registrable domain by SchemefulSite constructor.)
  225. EXPECT_TRUE(SiteForCookies::FromWire(
  226. SchemefulSite(GURL("http://sub.example.test")), false, &out));
  227. EXPECT_FALSE(out.IsNull());
  228. EXPECT_EQ(
  229. "SiteForCookies: {site=http://example.test; schemefully_same=false}",
  230. out.ToDebugString());
  231. // IP address is fine.
  232. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("https://127.0.0.1")),
  233. true, &out));
  234. EXPECT_FALSE(out.IsNull());
  235. EXPECT_EQ("SiteForCookies: {site=https://127.0.0.1; schemefully_same=true}",
  236. out.ToDebugString());
  237. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("https://127.0.0.1")),
  238. false, &out));
  239. EXPECT_FALSE(out.IsNull());
  240. EXPECT_EQ("SiteForCookies: {site=https://127.0.0.1; schemefully_same=false}",
  241. out.ToDebugString());
  242. // An actual eTLD+1 is fine.
  243. EXPECT_TRUE(SiteForCookies::FromWire(
  244. SchemefulSite(GURL("http://example.test")), true, &out));
  245. EXPECT_FALSE(out.IsNull());
  246. EXPECT_EQ("SiteForCookies: {site=http://example.test; schemefully_same=true}",
  247. out.ToDebugString());
  248. }
  249. // Similar to SchemelessSiteForCookiesTest_Wire except that schemefully_same has
  250. // an effect (makes IsNull() return true if schemefully_same is false).
  251. TEST(SiteForCookiesTest, Wire) {
  252. SiteForCookies out;
  253. // Empty one.
  254. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(), false, &out));
  255. EXPECT_TRUE(out.IsNull());
  256. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(), true, &out));
  257. EXPECT_TRUE(out.IsNull());
  258. // Not a valid site. (Scheme should have been converted to https.)
  259. EXPECT_FALSE(SiteForCookies::FromWire(
  260. SchemefulSite(GURL("wss://host.example.test")), false, &out));
  261. EXPECT_TRUE(out.IsNull());
  262. // Not a valid scheme. (Same result as opaque SchemefulSite.)
  263. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("aH://example.test")),
  264. false, &out));
  265. EXPECT_TRUE(out.IsNull());
  266. // Not a eTLD + 1 (or something hosty), but this is fine. (Is converted to a
  267. // registrable domain by SchemefulSite constructor.)
  268. EXPECT_TRUE(SiteForCookies::FromWire(
  269. SchemefulSite(GURL("http://sub.example.test")), false, &out));
  270. EXPECT_TRUE(out.IsNull());
  271. EXPECT_EQ(
  272. "SiteForCookies: {site=http://example.test; schemefully_same=false}",
  273. out.ToDebugString());
  274. // IP address is fine.
  275. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("https://127.0.0.1")),
  276. true, &out));
  277. EXPECT_FALSE(out.IsNull());
  278. EXPECT_EQ("SiteForCookies: {site=https://127.0.0.1; schemefully_same=true}",
  279. out.ToDebugString());
  280. // This one's schemefully_same is false
  281. EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("https://127.0.0.1")),
  282. false, &out));
  283. EXPECT_TRUE(out.IsNull());
  284. EXPECT_EQ("SiteForCookies: {site=https://127.0.0.1; schemefully_same=false}",
  285. out.ToDebugString());
  286. // An actual eTLD+1 is fine.
  287. EXPECT_TRUE(SiteForCookies::FromWire(
  288. SchemefulSite(GURL("http://example.test")), true, &out));
  289. EXPECT_FALSE(out.IsNull());
  290. EXPECT_EQ("SiteForCookies: {site=http://example.test; schemefully_same=true}",
  291. out.ToDebugString());
  292. // This one's schemefully_same is false.
  293. EXPECT_TRUE(SiteForCookies::FromWire(
  294. SchemefulSite(GURL("http://example.test")), false, &out));
  295. EXPECT_TRUE(out.IsNull());
  296. EXPECT_EQ(
  297. "SiteForCookies: {site=http://example.test; schemefully_same=false}",
  298. out.ToDebugString());
  299. }
  300. TEST(SiteForCookiesTest, SchemefulSite) {
  301. const char* kTestCases[] = {"opaque.com",
  302. "http://a.com",
  303. "https://sub1.example.com:42/something",
  304. "https://a.com",
  305. "ws://a.com",
  306. "wss://a.com",
  307. "file://a.com",
  308. "file://folder1/folder2/file.txt",
  309. "file:///file.txt"};
  310. for (std::string url : kTestCases) {
  311. url::Origin origin = url::Origin::Create(GURL(url));
  312. SiteForCookies from_origin = SiteForCookies::FromOrigin(origin);
  313. SchemefulSite schemeful_site = SchemefulSite(origin);
  314. SiteForCookies from_schemeful_site = SiteForCookies(schemeful_site);
  315. EXPECT_TRUE(from_origin.IsEquivalent(from_schemeful_site));
  316. EXPECT_TRUE(from_schemeful_site.IsEquivalent(from_origin));
  317. }
  318. }
  319. TEST(SiteForCookiesTest, CompareWithFrameTreeSiteAndRevise) {
  320. SchemefulSite secure_example = SchemefulSite(GURL("https://example.com"));
  321. SchemefulSite insecure_example = SchemefulSite(GURL("http://example.com"));
  322. SchemefulSite secure_other = SchemefulSite(GURL("https://other.com"));
  323. SchemefulSite insecure_other = SchemefulSite(GURL("http://other.com"));
  324. // Other scheme tests.
  325. url::ScopedSchemeRegistryForTests scoped_registry;
  326. AddStandardScheme("other", url::SCHEME_WITH_HOST);
  327. SchemefulSite file_scheme =
  328. SchemefulSite(GURL("file:///C:/Users/Default/Pictures/photo.png"));
  329. SchemefulSite file_scheme2 = SchemefulSite(GURL("file:///C:/file.txt"));
  330. SchemefulSite other_scheme = SchemefulSite(GURL("other://"));
  331. // This function should work the same regardless the state of Schemeful
  332. // Same-Site.
  333. for (const bool toggle : {false, true}) {
  334. base::test::ScopedFeatureList scope_feature_list;
  335. scope_feature_list.InitWithFeatureState(features::kSchemefulSameSite,
  336. toggle);
  337. SiteForCookies candidate1 = SiteForCookies(secure_example);
  338. EXPECT_TRUE(candidate1.CompareWithFrameTreeSiteAndRevise(secure_example));
  339. EXPECT_FALSE(candidate1.site().opaque());
  340. EXPECT_TRUE(candidate1.schemefully_same());
  341. SiteForCookies candidate2 = SiteForCookies(secure_example);
  342. EXPECT_TRUE(candidate2.CompareWithFrameTreeSiteAndRevise(insecure_example));
  343. EXPECT_FALSE(candidate2.site().opaque());
  344. EXPECT_FALSE(candidate2.schemefully_same());
  345. SiteForCookies candidate3 = SiteForCookies(secure_example);
  346. EXPECT_FALSE(candidate3.CompareWithFrameTreeSiteAndRevise(secure_other));
  347. EXPECT_TRUE(candidate3.site().opaque());
  348. // schemefully_same is N/A if the site() is opaque.
  349. SiteForCookies candidate4 = SiteForCookies(secure_example);
  350. EXPECT_FALSE(candidate4.CompareWithFrameTreeSiteAndRevise(insecure_other));
  351. EXPECT_TRUE(candidate4.site().opaque());
  352. // schemefully_same is N/A if the site() is opaque.
  353. // This function's check is bi-directional, so try reversed pairs just in
  354. // case.
  355. SiteForCookies candidate2_reversed = SiteForCookies(insecure_example);
  356. EXPECT_TRUE(
  357. candidate2_reversed.CompareWithFrameTreeSiteAndRevise(secure_example));
  358. EXPECT_FALSE(candidate2_reversed.site().opaque());
  359. EXPECT_FALSE(candidate2_reversed.schemefully_same());
  360. SiteForCookies candidate3_reversed = SiteForCookies(secure_other);
  361. EXPECT_FALSE(
  362. candidate3_reversed.CompareWithFrameTreeSiteAndRevise(secure_example));
  363. EXPECT_TRUE(candidate3_reversed.site().opaque());
  364. // schemefully_same is N/A if the site() is opaque.
  365. SiteForCookies candidate4_reversed = SiteForCookies(insecure_other);
  366. EXPECT_FALSE(
  367. candidate4_reversed.CompareWithFrameTreeSiteAndRevise(secure_example));
  368. EXPECT_TRUE(candidate4_reversed.site().opaque());
  369. // schemefully_same is N/A if the site() is opaque.
  370. // Now try some different schemes.
  371. SiteForCookies candidate5 = SiteForCookies(file_scheme);
  372. EXPECT_TRUE(candidate5.CompareWithFrameTreeSiteAndRevise(file_scheme2));
  373. EXPECT_FALSE(candidate5.site().opaque());
  374. EXPECT_TRUE(candidate5.schemefully_same());
  375. SiteForCookies candidate6 = SiteForCookies(file_scheme);
  376. EXPECT_FALSE(candidate6.CompareWithFrameTreeSiteAndRevise(other_scheme));
  377. EXPECT_TRUE(candidate6.site().opaque());
  378. // schemefully_same is N/A if the site() is opaque.
  379. SiteForCookies candidate5_reversed = SiteForCookies(file_scheme2);
  380. EXPECT_TRUE(
  381. candidate5_reversed.CompareWithFrameTreeSiteAndRevise(file_scheme));
  382. EXPECT_FALSE(candidate5_reversed.site().opaque());
  383. EXPECT_TRUE(candidate5_reversed.schemefully_same());
  384. SiteForCookies candidate6_reversed = SiteForCookies(other_scheme);
  385. EXPECT_FALSE(
  386. candidate6_reversed.CompareWithFrameTreeSiteAndRevise(file_scheme));
  387. EXPECT_TRUE(candidate6_reversed.site().opaque());
  388. // schemefully_same is N/A if the site() is opaque.
  389. }
  390. }
  391. TEST(SiteForCookiesTest, CompareWithFrameTreeSiteAndReviseOpaque) {
  392. url::Origin opaque1 = url::Origin();
  393. url::Origin opaque2 = url::Origin();
  394. SchemefulSite opaque_site1 = SchemefulSite(opaque1);
  395. SchemefulSite opaque_site2 = SchemefulSite(opaque2);
  396. SchemefulSite example = SchemefulSite(GURL("https://example.com"));
  397. // Opaque origins are able to match on the frame comparison.
  398. SiteForCookies candidate1 = SiteForCookies(opaque_site1);
  399. EXPECT_TRUE(candidate1.CompareWithFrameTreeSiteAndRevise(opaque_site1));
  400. EXPECT_TRUE(candidate1.site().opaque());
  401. // schemefully_same is N/A if the site() is opaque.
  402. EXPECT_EQ(candidate1.site(), opaque_site1);
  403. SiteForCookies candidate2 = SiteForCookies(opaque_site1);
  404. EXPECT_TRUE(candidate2.CompareWithFrameTreeSiteAndRevise(opaque_site2));
  405. EXPECT_TRUE(candidate2.site().opaque());
  406. // schemefully_same is N/A if the site() is opaque.
  407. EXPECT_EQ(candidate2.site(), opaque_site1);
  408. // But if only one is opaque they won't match.
  409. SiteForCookies candidate3 = SiteForCookies(example);
  410. EXPECT_FALSE(candidate3.CompareWithFrameTreeSiteAndRevise(opaque_site1));
  411. EXPECT_TRUE(candidate3.site().opaque());
  412. // schemefully_same is N/A if the site() is opaque.
  413. EXPECT_NE(candidate3.site(), opaque_site1);
  414. SiteForCookies candidate4 = SiteForCookies(opaque_site1);
  415. EXPECT_FALSE(candidate4.CompareWithFrameTreeSiteAndRevise(example));
  416. EXPECT_TRUE(candidate4.site().opaque());
  417. // schemefully_same is N/A if the site() is opaque.
  418. EXPECT_EQ(candidate4.site(), opaque_site1);
  419. }
  420. TEST(SiteForCookiesTest, NotSchemefullySameEquivalent) {
  421. SiteForCookies first =
  422. SiteForCookies::FromUrl(GURL("https://www.example.com"));
  423. SiteForCookies second =
  424. SiteForCookies::FromUrl(GURL("https://www.example.com"));
  425. // Smoke check that two SFCs should match when they're the same.
  426. EXPECT_TRUE(first.IsEquivalent(second));
  427. EXPECT_TRUE(second.IsEquivalent(first));
  428. // Two SFC should not be equivalent to each other when one of their
  429. // schemefully_same_ flags is false, even if they're otherwise the same, when
  430. // Schemeful Same-Site is enabled.
  431. second.SetSchemefullySameForTesting(false);
  432. EXPECT_FALSE(first.IsEquivalent(second));
  433. EXPECT_FALSE(second.IsEquivalent(first));
  434. // However, they should match if both their schemefully_same_ flags are false.
  435. // Because they're both considered null at that point.
  436. first.SetSchemefullySameForTesting(false);
  437. EXPECT_TRUE(first.IsEquivalent(second));
  438. EXPECT_TRUE(second.IsEquivalent(first));
  439. }
  440. } // namespace
  441. TEST(SiteForCookiesTest, SameScheme) {
  442. struct TestCase {
  443. const char* first;
  444. const char* second;
  445. bool expected_value;
  446. };
  447. const TestCase kTestCases[] = {
  448. {"http://a.com", "http://a.com", true},
  449. {"https://a.com", "https://a.com", true},
  450. {"ws://a.com", "ws://a.com", true},
  451. {"wss://a.com", "wss://a.com", true},
  452. {"https://a.com", "wss://a.com", true},
  453. {"wss://a.com", "https://a.com", true},
  454. {"http://a.com", "ws://a.com", true},
  455. {"ws://a.com", "http://a.com", true},
  456. {"file://a.com", "file://a.com", true},
  457. {"file://folder1/folder2/file.txt", "file://folder1/folder2/file.txt",
  458. true},
  459. {"ftp://a.com", "ftp://a.com", true},
  460. {"http://a.com", "file://a.com", false},
  461. {"ws://a.com", "wss://a.com", false},
  462. {"wss://a.com", "ws://a.com", false},
  463. {"https://a.com", "http://a.com", false},
  464. {"file://a.com", "https://a.com", false},
  465. {"https://a.com", "file://a.com", false},
  466. {"file://a.com", "ftp://a.com", false},
  467. {"ftp://a.com", "file://a.com", false},
  468. };
  469. for (const TestCase& t : kTestCases) {
  470. SiteForCookies first = SiteForCookies::FromUrl(GURL(t.first));
  471. SchemefulSite second(GURL(t.second));
  472. EXPECT_FALSE(first.IsNull());
  473. first.MarkIfCrossScheme(second);
  474. EXPECT_EQ(first.schemefully_same(), t.expected_value);
  475. }
  476. }
  477. TEST(SiteForCookiesTest, SameSchemeOpaque) {
  478. url::Origin not_opaque_secure =
  479. url::Origin::Create(GURL("https://site.example"));
  480. url::Origin not_opaque_nonsecure =
  481. url::Origin::Create(GURL("http://site.example"));
  482. // Check an opaque origin made from a triple origin and one from the default
  483. // constructor.
  484. const url::Origin kOpaqueOrigins[] = {
  485. not_opaque_secure.DeriveNewOpaqueOrigin(),
  486. not_opaque_nonsecure.DeriveNewOpaqueOrigin(), url::Origin()};
  487. for (const url::Origin& origin : kOpaqueOrigins) {
  488. SiteForCookies secure_sfc = SiteForCookies::FromOrigin(not_opaque_secure);
  489. EXPECT_FALSE(secure_sfc.IsNull());
  490. SiteForCookies nonsecure_sfc =
  491. SiteForCookies::FromOrigin(not_opaque_nonsecure);
  492. EXPECT_FALSE(nonsecure_sfc.IsNull());
  493. SchemefulSite site(origin);
  494. EXPECT_TRUE(secure_sfc.schemefully_same());
  495. secure_sfc.MarkIfCrossScheme(site);
  496. EXPECT_FALSE(secure_sfc.schemefully_same());
  497. EXPECT_TRUE(nonsecure_sfc.schemefully_same());
  498. nonsecure_sfc.MarkIfCrossScheme(site);
  499. EXPECT_FALSE(nonsecure_sfc.schemefully_same());
  500. SiteForCookies opaque_sfc = SiteForCookies(site);
  501. EXPECT_TRUE(opaque_sfc.IsNull());
  502. // Slightly implementation detail specific as the value isn't relevant for
  503. // null SFCs.
  504. EXPECT_FALSE(nonsecure_sfc.schemefully_same());
  505. }
  506. }
  507. // Quick correctness check that the less-than operator works as expected.
  508. TEST(SiteForCookiesTest, LessThan) {
  509. SiteForCookies first = SiteForCookies::FromUrl(GURL("https://example.com"));
  510. SiteForCookies second =
  511. SiteForCookies::FromUrl(GURL("https://examplelonger.com"));
  512. SiteForCookies third =
  513. SiteForCookies::FromUrl(GURL("https://examplelongerstill.com"));
  514. SiteForCookies null1 = SiteForCookies();
  515. SiteForCookies null2 =
  516. SiteForCookies::FromUrl(GURL("https://examplelongerstillstill.com"));
  517. null2.SetSchemefullySameForTesting(false);
  518. EXPECT_LT(first, second);
  519. EXPECT_LT(second, third);
  520. EXPECT_LT(first, third);
  521. EXPECT_LT(null1, first);
  522. EXPECT_LT(null2, first);
  523. EXPECT_FALSE(second < first);
  524. EXPECT_FALSE(first < null1);
  525. EXPECT_FALSE(first < null2);
  526. EXPECT_FALSE(null1 < null2);
  527. EXPECT_FALSE(null2 < null1);
  528. }
  529. } // namespace net