Skip to content

Commit 61efb6a

Browse files
authored
Merge pull request #7387 from brave/ephemeral-cookie-storage-mimimal-network-cookies
Add ephemeral storage support for network cookies
2 parents b945014 + f02a83a commit 61efb6a

File tree

4 files changed

+191
-10
lines changed

4 files changed

+191
-10
lines changed

browser/ephemeral_storage/ephemeral_storage_browsertest.cc

+115-10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "components/prefs/pref_service.h"
1919
#include "content/public/browser/notification_types.h"
2020
#include "content/public/browser/render_frame_host.h"
21+
#include "content/public/browser/storage_partition.h"
2122
#include "content/public/browser/web_contents.h"
2223
#include "content/public/test/browser_test.h"
2324
#include "content/public/test/test_navigation_observer.h"
@@ -115,19 +116,23 @@ class EphemeralStorageBrowserTest : public InProcessBrowserTest {
115116
content_settings, brave_shields::ControlType::ALLOW, GURL());
116117
}
117118

119+
void SetValuesInFrame(RenderFrameHost* frame,
120+
std::string storage_value,
121+
std::string cookie_value) {
122+
SetStorageValueInFrame(frame, storage_value, StorageType::Local);
123+
SetStorageValueInFrame(frame, storage_value, StorageType::Session);
124+
SetCookieInFrame(frame, cookie_value);
125+
}
126+
118127
void SetValuesInFrames(WebContents* web_contents,
119128
std::string storage_value,
120129
std::string cookie_value) {
121-
auto set_values_in_frame = [&](RenderFrameHost* frame) {
122-
SetStorageValueInFrame(frame, storage_value, StorageType::Local);
123-
SetStorageValueInFrame(frame, storage_value, StorageType::Session);
124-
SetCookieInFrame(frame, cookie_value);
125-
};
126-
127-
RenderFrameHost* main_frame = web_contents->GetMainFrame();
128-
set_values_in_frame(main_frame);
129-
set_values_in_frame(content::ChildFrameAt(main_frame, 0));
130-
set_values_in_frame(content::ChildFrameAt(main_frame, 1));
130+
RenderFrameHost* main = web_contents->GetMainFrame();
131+
SetValuesInFrame(main, storage_value, cookie_value);
132+
SetValuesInFrame(content::ChildFrameAt(main, 0), storage_value,
133+
cookie_value);
134+
SetValuesInFrame(content::ChildFrameAt(main, 1), storage_value,
135+
cookie_value);
131136
}
132137

133138
struct ValuesFromFrame {
@@ -449,3 +454,103 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest,
449454
EXPECT_EQ("", private_values.iframe_1.cookies);
450455
EXPECT_EQ("", private_values.iframe_2.cookies);
451456
}
457+
458+
IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest,
459+
NavigationCookiesArePartitioned) {
460+
AllowAllCookies();
461+
462+
GURL a_site_set_cookie_url = https_server_.GetURL(
463+
"a.com", "/set-cookie?name=acom;path=/;SameSite=None;Secure");
464+
GURL b_site_set_cookie_url = https_server_.GetURL(
465+
"b.com", "/set-cookie?name=bcom;path=/;SameSite=None;Secure");
466+
467+
ui_test_utils::NavigateToURL(browser(), a_site_set_cookie_url);
468+
ui_test_utils::NavigateToURL(browser(), b_site_set_cookie_url);
469+
ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_);
470+
471+
std::string a_cookie =
472+
content::GetCookies(browser()->profile(), GURL("https://a.com/"));
473+
std::string b_cookie =
474+
content::GetCookies(browser()->profile(), GURL("https://b.com/"));
475+
EXPECT_EQ("name=acom", a_cookie);
476+
EXPECT_EQ("name=bcom", b_cookie);
477+
478+
// The third-party iframe should not have the b.com cookie that was set on the
479+
// main frame.
480+
auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
481+
RenderFrameHost* main_frame = web_contents->GetMainFrame();
482+
RenderFrameHost* iframe_a = content::ChildFrameAt(main_frame, 0);
483+
RenderFrameHost* iframe_b = content::ChildFrameAt(main_frame, 1);
484+
ASSERT_EQ("", GetCookiesInFrame(iframe_a));
485+
ASSERT_EQ("", GetCookiesInFrame(iframe_b));
486+
487+
// Setting the cookie directly on the third-party iframe should only set the
488+
// cookie in the ephemeral storage area for that frame.
489+
GURL b_site_set_ephemeral_cookie_url = https_server_.GetURL(
490+
"b.com", "/set-cookie?name=bcom_ephemeral;path=/;SameSite=None;Secure");
491+
NavigateIframeToURL(web_contents, "third_party_iframe_a",
492+
b_site_set_ephemeral_cookie_url);
493+
ASSERT_EQ("name=bcom_ephemeral", GetCookiesInFrame(iframe_a));
494+
ASSERT_EQ("name=bcom_ephemeral", GetCookiesInFrame(iframe_b));
495+
496+
// The cookie set in the ephemeral area should not visible in the main
497+
// cookie storage.
498+
b_cookie = content::GetCookies(browser()->profile(), GURL("https://b.com/"));
499+
EXPECT_EQ("name=bcom", b_cookie);
500+
501+
// Navigating to a new TLD should clear all ephemeral cookies.
502+
ui_test_utils::NavigateToURL(browser(), b_site_ephemeral_storage_url_);
503+
ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_);
504+
505+
ValuesFromFrames values_after = GetValuesFromFrames(web_contents);
506+
EXPECT_EQ("name=acom", values_after.main_frame.cookies);
507+
EXPECT_EQ("", values_after.iframe_1.cookies);
508+
EXPECT_EQ("", values_after.iframe_2.cookies);
509+
}
510+
511+
IN_PROC_BROWSER_TEST_F(EphemeralStorageBrowserTest,
512+
FirstPartyNestedInThirdParty) {
513+
AllowAllCookies();
514+
515+
auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
516+
517+
GURL a_site_set_cookie_url = https_server_.GetURL(
518+
"a.com", "/set-cookie?name=acom;path=/;SameSite=None;Secure");
519+
ui_test_utils::NavigateToURL(browser(), a_site_set_cookie_url);
520+
ui_test_utils::NavigateToURL(browser(), a_site_ephemeral_storage_url_);
521+
522+
RenderFrameHost* site_a_main_frame = web_contents->GetMainFrame();
523+
RenderFrameHost* nested_frames_tab =
524+
content::ChildFrameAt(site_a_main_frame, 3);
525+
ASSERT_NE(nested_frames_tab, nullptr);
526+
RenderFrameHost* first_party_nested_acom =
527+
content::ChildFrameAt(nested_frames_tab, 2);
528+
ASSERT_NE(first_party_nested_acom, nullptr);
529+
530+
WebContents* site_b_tab = LoadURLInNewTab(b_site_ephemeral_storage_url_);
531+
RenderFrameHost* site_b_main_frame = site_b_tab->GetMainFrame();
532+
RenderFrameHost* third_party_nested_acom =
533+
content::ChildFrameAt(site_b_main_frame, 2);
534+
ASSERT_NE(first_party_nested_acom, nullptr);
535+
536+
ASSERT_EQ("name=acom", GetCookiesInFrame(site_a_main_frame));
537+
ASSERT_EQ("name=acom", GetCookiesInFrame(first_party_nested_acom));
538+
ASSERT_EQ("", GetCookiesInFrame(third_party_nested_acom));
539+
540+
SetValuesInFrame(site_a_main_frame, "first-party-a.com",
541+
"name=first-party-a.com");
542+
SetValuesInFrame(third_party_nested_acom, "third-party-a.com",
543+
"name=third-party-a.com");
544+
545+
ValuesFromFrame first_party_values =
546+
GetValuesFromFrame(first_party_nested_acom);
547+
EXPECT_EQ("first-party-a.com", first_party_values.local_storage);
548+
EXPECT_EQ("first-party-a.com", first_party_values.session_storage);
549+
EXPECT_EQ("name=first-party-a.com", first_party_values.cookies);
550+
551+
ValuesFromFrame third_party_values =
552+
GetValuesFromFrame(third_party_nested_acom);
553+
EXPECT_EQ("third-party-a.com", third_party_values.local_storage);
554+
EXPECT_EQ("third-party-a.com", third_party_values.session_storage);
555+
EXPECT_EQ("name=third-party-a.com", third_party_values.cookies);
556+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
4+
* You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
#include "net/url_request/url_request_http_job.h"
7+
8+
#include "base/bind.h"
9+
#include "net/base/features.h"
10+
#include "net/base/isolation_info.h"
11+
#include "net/cookies/cookie_monster.h"
12+
#include "net/url_request/url_request.h"
13+
14+
namespace {
15+
16+
bool ShouldUseEphemeralStorage(net::URLRequestHttpJob* http_job) {
17+
if (!base::FeatureList::IsEnabled(net::features::kBraveEphemeralStorage))
18+
return false;
19+
20+
const net::IsolationInfo& isolation_info =
21+
http_job->request()->isolation_info();
22+
if (!isolation_info.top_frame_origin().has_value() ||
23+
!isolation_info.frame_origin().has_value())
24+
return false;
25+
if (*isolation_info.top_frame_origin() == *isolation_info.frame_origin())
26+
return false;
27+
28+
return true;
29+
}
30+
31+
} // namespace
32+
33+
#define BRAVE_ADDCOOKIEHEADERANDSTART \
34+
if (ShouldUseEphemeralStorage(this)) \
35+
static_cast<CookieMonster*>(cookie_store) \
36+
->GetEphemeralCookieListWithOptionsAsync( \
37+
request_->url(), \
38+
request()->isolation_info().top_frame_origin()->GetURL(), options, \
39+
base::BindOnce(&URLRequestHttpJob::SetCookieHeaderAndStart, \
40+
weak_factory_.GetWeakPtr(), options)); \
41+
else
42+
43+
#define BRAVE_SAVECOOKIESANDNOTIFYHEADERSCOMPLETE \
44+
if (ShouldUseEphemeralStorage(this)) \
45+
static_cast<CookieMonster*>(request_->context()->cookie_store()) \
46+
->SetEphemeralCanonicalCookieAsync( \
47+
std::move(cookie), request_->url(), \
48+
request()->isolation_info().top_frame_origin()->GetURL(), options, \
49+
base::BindOnce(&URLRequestHttpJob::OnSetCookieResult, \
50+
weak_factory_.GetWeakPtr(), options, \
51+
cookie_to_return, cookie_string)); \
52+
else
53+
54+
#include "../../../../../net/url_request/url_request_http_job.cc"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
2+
index f5e754f4ea0288a685a6932b00f692e3c6638621..d7da91c3607d205fd19cae3be369d4e58989f8bb 100644
3+
--- a/net/url_request/url_request_http_job.cc
4+
+++ b/net/url_request/url_request_http_job.cc
5+
@@ -583,6 +583,7 @@ void URLRequestHttpJob::AddCookieHeaderAndStart() {
6+
net::cookie_util::ComputeSameSiteContextForRequest(
7+
request_->method(), request_->url(), request_->site_for_cookies(),
8+
request_->initiator(), force_ignore_site_for_cookies));
9+
+ BRAVE_ADDCOOKIEHEADERANDSTART
10+
cookie_store->GetCookieListWithOptionsAsync(
11+
request_->url(), options,
12+
base::BindOnce(&URLRequestHttpJob::SetCookieHeaderAndStart,
13+
@@ -770,6 +771,7 @@ void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) {
14+
continue;
15+
}
16+
17+
+ BRAVE_SAVECOOKIESANDNOTIFYHEADERSCOMPLETE
18+
request_->context()->cookie_store()->SetCanonicalCookieAsync(
19+
std::move(cookie), request_->url(), options,
20+
base::BindOnce(&URLRequestHttpJob::OnSetCookieResult,

test/data/ephemeral_storage.html

+2
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
<body>
33
<iframe src="/cross-site/b.com/simple.html" id="third_party_iframe_a"></iframe>
44
<iframe src="/cross-site/b.com/simple.html" id="third_party_iframe_b"></iframe>
5+
<iframe src="/cross-site/a.com/simple.html" id="first_party_iframe"></iframe>
6+
<iframe src="/cross-site/b.com/ephemeral_storage.html" id="nested_iframe"></iframe>
57
</body></html>

0 commit comments

Comments
 (0)