Cleanup cookies set by server redirects when FBD is enabled. (#27944)
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/escape.h"
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
@@ -41,7 +42,7 @@
|
||||
#include "content/public/test/test_navigation_observer.h"
|
||||
#include "net/base/features.h"
|
||||
#include "net/dns/mock_host_resolver.h"
|
||||
#include "net/test/embedded_test_server/default_handlers.h"
|
||||
#include "net/http/http_status_code.h"
|
||||
#include "net/test/embedded_test_server/http_response.h"
|
||||
#include "net/test/embedded_test_server/request_handler_util.h"
|
||||
#include "services/network/public/cpp/network_switches.h"
|
||||
@@ -106,6 +107,39 @@ std::unique_ptr<HttpResponse> HandleFileRequestWithCustomHeaders(
|
||||
return http_response;
|
||||
}
|
||||
|
||||
// This mostly mimics the behavior of /cross-site-with-cookie handler, but with
|
||||
// additional cookie attributes set.
|
||||
std::unique_ptr<HttpResponse> HandleCrossSiteRedirectWithSiteCookie(
|
||||
EmbeddedTestServer* server,
|
||||
const HttpRequest& request) {
|
||||
const std::string prefix = "/cross-site-with-site-cookie";
|
||||
if (!net::test_server::ShouldHandle(request, prefix)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string dest_all = base::UnescapeBinaryURLComponent(
|
||||
request.relative_url.substr(prefix.size() + 1));
|
||||
|
||||
std::string dest;
|
||||
size_t delimiter = dest_all.find("/");
|
||||
if (delimiter != std::string::npos) {
|
||||
dest = base::StringPrintf(
|
||||
"//%s:%hu/%s", dest_all.substr(0, delimiter).c_str(), server->port(),
|
||||
dest_all.substr(delimiter + 1).c_str());
|
||||
}
|
||||
|
||||
auto http_response = std::make_unique<BasicHttpResponse>();
|
||||
http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
|
||||
http_response->AddCustomHeader("Location", dest);
|
||||
http_response->AddCustomHeader(
|
||||
"Set-Cookie",
|
||||
"server-redirect=true;path=/;SameSite=None;Secure;Max-Age=600");
|
||||
http_response->set_content_type("text/html");
|
||||
http_response->set_content(
|
||||
base::StringPrintf("<!doctype html><p>Redirecting to %s", dest.c_str()));
|
||||
return http_response;
|
||||
}
|
||||
|
||||
class BrowsingDataRemoverObserver
|
||||
: public content::BrowsingDataRemover::Observer {
|
||||
public:
|
||||
@@ -181,6 +215,8 @@ void EphemeralStorageBrowserTest::SetUpOnMainThread() {
|
||||
base::PathService::Get(brave::DIR_TEST_DATA, &test_data_dirs[0]);
|
||||
base::PathService::Get(content::DIR_TEST_DATA, &test_data_dirs[1]);
|
||||
|
||||
https_server_.RegisterRequestHandler(base::BindRepeating(
|
||||
&HandleCrossSiteRedirectWithSiteCookie, &https_server_));
|
||||
https_server_.RegisterDefaultHandler(base::BindRepeating(
|
||||
&HandleFileRequestWithCustomHeaders,
|
||||
base::Unretained(&http_request_monitor_), test_data_dirs));
|
||||
|
||||
@@ -271,6 +271,49 @@ IN_PROC_BROWSER_TEST_F(EphemeralStorageForgetByDefaultBrowserTest,
|
||||
EXPECT_EQ("", values_site_b.iframe_2.cookies);
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(EphemeralStorageForgetByDefaultBrowserTest,
|
||||
NavigationRedirectCookiesAreCleared) {
|
||||
brave_shields::SetForgetFirstPartyStorageEnabled(content_settings(), true,
|
||||
GURL());
|
||||
|
||||
const GURL a_site_url =
|
||||
https_server_.GetURL("0.com",
|
||||
"/cross-site-with-site-cookie/1.com/"
|
||||
"cross-site-with-site-cookie/a.com/empty.html");
|
||||
|
||||
WebContents* site_a = LoadURLInNewTab(a_site_url);
|
||||
|
||||
// Default cookie storage request should return non empty results for 0.com
|
||||
// and 1.com as these websites should set cookies on server redirect.
|
||||
EXPECT_FALSE(content::GetCookies(browser()->profile(),
|
||||
https_server_.GetURL("0.com", "/"))
|
||||
.empty());
|
||||
EXPECT_FALSE(content::GetCookies(browser()->profile(),
|
||||
https_server_.GetURL("1.com", "/"))
|
||||
.empty());
|
||||
|
||||
// a.com/empty.html should not set cookies.
|
||||
EXPECT_TRUE(content::GetCookies(browser()->profile(),
|
||||
https_server_.GetURL("a.com", "/"))
|
||||
.empty());
|
||||
|
||||
// Navigating to a new TLD should clear all ephemeral cookies after keep-alive
|
||||
// timeout.
|
||||
ASSERT_TRUE(content::NavigateToURL(site_a, c_site_ephemeral_storage_url_));
|
||||
EXPECT_EQ(3u, WaitForCleanupAfterKeepAlive());
|
||||
|
||||
// Cookies should be cleared for 0.com and 1.com.
|
||||
EXPECT_TRUE(content::GetCookies(browser()->profile(),
|
||||
https_server_.GetURL("0.com", "/"))
|
||||
.empty());
|
||||
EXPECT_TRUE(content::GetCookies(browser()->profile(),
|
||||
https_server_.GetURL("1.com", "/"))
|
||||
.empty());
|
||||
EXPECT_TRUE(content::GetCookies(browser()->profile(),
|
||||
https_server_.GetURL("a.com", "/"))
|
||||
.empty());
|
||||
}
|
||||
|
||||
IN_PROC_BROWSER_TEST_F(EphemeralStorageForgetByDefaultBrowserTest,
|
||||
PRE_ForgetFirstPartyAfterRestart) {
|
||||
const GURL a_site_set_cookie_url(
|
||||
|
||||
@@ -60,6 +60,38 @@ EphemeralStorageTabHelper::GetEphemeralStorageToken(const url::Origin& origin) {
|
||||
|
||||
void EphemeralStorageTabHelper::WebContentsDestroyed() {}
|
||||
|
||||
void EphemeralStorageTabHelper::DidStartNavigation(
|
||||
NavigationHandle* navigation_handle) {
|
||||
if (!navigation_handle->IsInMainFrame() ||
|
||||
navigation_handle->IsSameDocument()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CreateProvisionalTLDEphemeralLifetime(navigation_handle);
|
||||
}
|
||||
|
||||
void EphemeralStorageTabHelper::DidRedirectNavigation(
|
||||
NavigationHandle* navigation_handle) {
|
||||
if (!navigation_handle->IsInMainFrame() ||
|
||||
navigation_handle->IsSameDocument()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CreateProvisionalTLDEphemeralLifetime(navigation_handle);
|
||||
}
|
||||
|
||||
void EphemeralStorageTabHelper::DidFinishNavigation(
|
||||
NavigationHandle* navigation_handle) {
|
||||
if (!navigation_handle->IsInMainFrame() ||
|
||||
navigation_handle->IsSameDocument()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear all provisional ephemeral lifetimes. A committed ephemeral lifetime
|
||||
// is created in ReadyToCommitNavigation().
|
||||
provisional_tld_ephemeral_lifetimes_.clear();
|
||||
}
|
||||
|
||||
void EphemeralStorageTabHelper::ReadyToCommitNavigation(
|
||||
NavigationHandle* navigation_handle) {
|
||||
if (!navigation_handle->IsInMainFrame()) {
|
||||
@@ -96,6 +128,27 @@ void EphemeralStorageTabHelper::CreateEphemeralStorageAreasForDomainAndURL(
|
||||
browser_context, new_domain, site_instance->GetStoragePartitionConfig());
|
||||
}
|
||||
|
||||
void EphemeralStorageTabHelper::CreateProvisionalTLDEphemeralLifetime(
|
||||
NavigationHandle* navigation_handle) {
|
||||
const GURL& url = navigation_handle->GetURL();
|
||||
if (!url.SchemeIsHTTPOrHTTPS()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string new_domain = net::URLToEphemeralStorageDomain(url);
|
||||
if (new_domain.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* browser_context = web_contents()->GetBrowserContext();
|
||||
auto* site_instance = web_contents()->GetSiteInstance();
|
||||
|
||||
provisional_tld_ephemeral_lifetimes_.emplace(
|
||||
TLDEphemeralLifetime::GetOrCreate(
|
||||
browser_context, new_domain,
|
||||
site_instance->GetStoragePartitionConfig()));
|
||||
}
|
||||
|
||||
void EphemeralStorageTabHelper::UpdateShieldsState(const GURL& url) {
|
||||
if (!host_content_settings_map_ || !tld_ephemeral_lifetime_) {
|
||||
return;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "base/containers/flat_set.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/unguessable_token.h"
|
||||
#include "brave/browser/ephemeral_storage/tld_ephemeral_lifetime.h"
|
||||
@@ -45,10 +46,18 @@ class EphemeralStorageTabHelper
|
||||
friend class content::WebContentsUserData<EphemeralStorageTabHelper>;
|
||||
|
||||
// WebContentsObserver
|
||||
void DidStartNavigation(
|
||||
content::NavigationHandle* navigation_handle) override;
|
||||
void DidRedirectNavigation(
|
||||
content::NavigationHandle* navigation_handle) override;
|
||||
void DidFinishNavigation(
|
||||
content::NavigationHandle* navigation_handle) override;
|
||||
void ReadyToCommitNavigation(
|
||||
content::NavigationHandle* navigation_handle) override;
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
void CreateProvisionalTLDEphemeralLifetime(
|
||||
content::NavigationHandle* navigation_handle);
|
||||
void CreateEphemeralStorageAreasForDomainAndURL(const std::string& new_domain,
|
||||
const GURL& new_url);
|
||||
|
||||
@@ -57,6 +66,8 @@ class EphemeralStorageTabHelper
|
||||
const base::raw_ptr<HostContentSettingsMap> host_content_settings_map_;
|
||||
scoped_refptr<content_settings::CookieSettings> cookie_settings_;
|
||||
scoped_refptr<content::SessionStorageNamespace> session_storage_namespace_;
|
||||
base::flat_set<scoped_refptr<TLDEphemeralLifetime>>
|
||||
provisional_tld_ephemeral_lifetimes_;
|
||||
scoped_refptr<TLDEphemeralLifetime> tld_ephemeral_lifetime_;
|
||||
|
||||
base::WeakPtrFactory<EphemeralStorageTabHelper> weak_factory_{this};
|
||||
|
||||
Reference in New Issue
Block a user