Add SameSite (same_site) and Priority attributes to CefCookie (fixes issue #2524)

This change also restores the Chromium default values for the
SameSiteByDefaultCookies and CookiesWithoutSameSiteMustBeSecure features. See
https://www.chromium.org/updates/same-site for feature details and rollout
timeline.
This commit is contained in:
Dmitry Azaraev
2020-04-24 17:48:16 -04:00
committed by Marshall Greenblatt
parent cbc0625272
commit be6af15754
10 changed files with 129 additions and 18 deletions

View File

@ -737,6 +737,25 @@ typedef struct _cef_urlparts_t {
cef_string_t fragment; cef_string_t fragment;
} cef_urlparts_t; } cef_urlparts_t;
///
// Cookie priority values.
///
typedef enum {
CEF_COOKIE_PRIORITY_LOW = -1,
CEF_COOKIE_PRIORITY_MEDIUM = 0,
CEF_COOKIE_PRIORITY_HIGH = 1,
} cef_cookie_priority_t;
///
// Cookie same site values.
///
typedef enum {
CEF_COOKIE_SAME_SITE_UNSPECIFIED,
CEF_COOKIE_SAME_SITE_NO_RESTRICTION,
CEF_COOKIE_SAME_SITE_LAX_MODE,
CEF_COOKIE_SAME_SITE_STRICT_MODE,
} cef_cookie_same_site_t;
/// ///
// Cookie information. // Cookie information.
/// ///
@ -791,6 +810,16 @@ typedef struct _cef_cookie_t {
/// ///
int has_expires; int has_expires;
cef_time_t expires; cef_time_t expires;
///
// Same site.
///
cef_cookie_same_site_t same_site;
///
// Priority.
///
cef_cookie_priority_t priority;
} cef_cookie_t; } cef_cookie_t;
/// ///

View File

@ -851,6 +851,8 @@ struct CefCookieTraits {
target->last_access = src->last_access; target->last_access = src->last_access;
target->has_expires = src->has_expires; target->has_expires = src->has_expires;
target->expires = src->expires; target->expires = src->expires;
target->same_site = src->same_site;
target->priority = src->priority;
} }
}; };

View File

@ -31,6 +31,7 @@
#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/cpp/simple_url_loader_stream_consumer.h" #include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h"
namespace { namespace {
@ -254,6 +255,23 @@ class CefBrowserURLRequest::Context
resource_request->render_frame_id = render_frame_id; resource_request->render_frame_id = render_frame_id;
// Behave the same as a subresource load.
resource_request->fetch_request_context_type =
static_cast<int>(blink::mojom::RequestContextType::SUBRESOURCE);
resource_request->resource_type =
static_cast<int>(blink::mojom::ResourceType::kSubResource);
// Set the origin to match the request.
const GURL& url = GURL(request_->GetURL().ToString());
resource_request->request_initiator = url::Origin::Create(url);
if (request_flags & UR_FLAG_ALLOW_STORED_CREDENTIALS) {
// Include SameSite cookies.
resource_request->attach_same_site_cookies = true;
resource_request->site_for_cookies =
net::SiteForCookies::FromOrigin(*resource_request->request_initiator);
}
// SimpleURLLoader is picky about the body contents. Try to populate them // SimpleURLLoader is picky about the body contents. Try to populate them
// correctly below. // correctly below.
auto request_body = resource_request->request_body; auto request_body = resource_request->request_body;

View File

@ -47,6 +47,9 @@ void SetCookieCallbackImpl(CefRefPtr<CefSetCookieCallback> callback,
net::CanonicalCookie::CookieInclusionStatus status) { net::CanonicalCookie::CookieInclusionStatus status) {
if (!callback.get()) if (!callback.get())
return; return;
if (!status.IsInclude()) {
LOG(WARNING) << "SetCookie failed with reason: " << status.GetDebugString();
}
CEF_POST_TASK(CEF_UIT, base::Bind(&CefSetCookieCallback::OnComplete, CEF_POST_TASK(CEF_UIT, base::Bind(&CefSetCookieCallback::OnComplete,
callback.get(), status.IsInclude())); callback.get(), status.IsInclude()));
} }
@ -203,6 +206,8 @@ bool CefCookieManagerImpl::VisitUrlCookies(
net::CookieOptions options; net::CookieOptions options;
if (includeHttpOnly) if (includeHttpOnly)
options.set_include_httponly(); options.set_include_httponly();
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
auto browser_context = GetBrowserContext(browser_context_getter_); auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context) if (!browser_context)
@ -239,13 +244,18 @@ bool CefCookieManagerImpl::SetCookie(const CefString& url,
if (cookie.has_expires) if (cookie.has_expires)
cef_time_to_basetime(cookie.expires, expiration_time); cef_time_to_basetime(cookie.expires, expiration_time);
net::CookieSameSite same_site =
net_service::MakeCookieSameSite(cookie.same_site);
net::CookiePriority priority =
net_service::MakeCookiePriority(cookie.priority);
auto canonical_cookie = net::CanonicalCookie::CreateSanitizedCookie( auto canonical_cookie = net::CanonicalCookie::CreateSanitizedCookie(
gurl, name, value, domain, path, gurl, name, value, domain, path,
base::Time(), // Creation time. base::Time(), // Creation time.
expiration_time, expiration_time,
base::Time(), // Last access time. base::Time(), // Last access time.
cookie.secure ? true : false, cookie.httponly ? true : false, cookie.secure ? true : false, cookie.httponly ? true : false, same_site,
net::CookieSameSite::UNSPECIFIED, net::COOKIE_PRIORITY_DEFAULT); priority);
if (!canonical_cookie) { if (!canonical_cookie) {
SetCookieCallbackImpl(callback, SetCookieCallbackImpl(callback,
@ -258,6 +268,8 @@ bool CefCookieManagerImpl::SetCookie(const CefString& url,
net::CookieOptions options; net::CookieOptions options;
if (cookie.httponly) if (cookie.httponly)
options.set_include_httponly(); options.set_include_httponly();
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::MakeInclusive());
auto browser_context = GetBrowserContext(browser_context_getter_); auto browser_context = GetBrowserContext(browser_context_getter_);
if (!browser_context) if (!browser_context)

View File

@ -620,18 +620,6 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
disable_features.push_back(network::features::kOutOfBlinkCors.name); disable_features.push_back(network::features::kOutOfBlinkCors.name);
} }
// TODO: Add support for creating cookies with SameSite attribute (see issue
// #2524)
if (net::features::kSameSiteByDefaultCookies.default_state ==
base::FEATURE_ENABLED_BY_DEFAULT) {
disable_features.push_back(net::features::kSameSiteByDefaultCookies.name);
}
if (net::features::kCookiesWithoutSameSiteMustBeSecure.default_state ==
base::FEATURE_ENABLED_BY_DEFAULT) {
disable_features.push_back(
net::features::kCookiesWithoutSameSiteMustBeSecure.name);
}
#if defined(OS_WIN) #if defined(OS_WIN)
if (features::kCalculateNativeWinOcclusion.default_state == if (features::kCalculateNativeWinOcclusion.default_state ==
base::FEATURE_ENABLED_BY_DEFAULT) { base::FEATURE_ENABLED_BY_DEFAULT) {

View File

@ -38,6 +38,30 @@ bool GetCookieDomain(const GURL& url,
result); result);
} }
cef_cookie_same_site_t MakeCefCookieSameSite(net::CookieSameSite value) {
switch (value) {
case net::CookieSameSite::UNSPECIFIED:
return CEF_COOKIE_SAME_SITE_UNSPECIFIED;
case net::CookieSameSite::NO_RESTRICTION:
return CEF_COOKIE_SAME_SITE_NO_RESTRICTION;
case net::CookieSameSite::LAX_MODE:
return CEF_COOKIE_SAME_SITE_LAX_MODE;
case net::CookieSameSite::STRICT_MODE:
return CEF_COOKIE_SAME_SITE_STRICT_MODE;
}
}
cef_cookie_priority_t MakeCefCookiePriority(net::CookiePriority value) {
switch (value) {
case net::COOKIE_PRIORITY_LOW:
return CEF_COOKIE_PRIORITY_LOW;
case net::COOKIE_PRIORITY_MEDIUM:
return CEF_COOKIE_PRIORITY_MEDIUM;
case net::COOKIE_PRIORITY_HIGH:
return CEF_COOKIE_PRIORITY_HIGH;
}
}
} // namespace } // namespace
const char kHTTPLocationHeaderName[] = "Location"; const char kHTTPLocationHeaderName[] = "Location";
@ -177,6 +201,30 @@ net::RedirectInfo MakeRedirectInfo(const network::ResourceRequest& request,
insecure_scheme_was_upgraded); insecure_scheme_was_upgraded);
} }
net::CookieSameSite MakeCookieSameSite(cef_cookie_same_site_t value) {
switch (value) {
case CEF_COOKIE_SAME_SITE_UNSPECIFIED:
return net::CookieSameSite::UNSPECIFIED;
case CEF_COOKIE_SAME_SITE_NO_RESTRICTION:
return net::CookieSameSite::NO_RESTRICTION;
case CEF_COOKIE_SAME_SITE_LAX_MODE:
return net::CookieSameSite::LAX_MODE;
case CEF_COOKIE_SAME_SITE_STRICT_MODE:
return net::CookieSameSite::STRICT_MODE;
}
}
net::CookiePriority MakeCookiePriority(cef_cookie_priority_t value) {
switch (value) {
case CEF_COOKIE_PRIORITY_LOW:
return net::COOKIE_PRIORITY_LOW;
case CEF_COOKIE_PRIORITY_MEDIUM:
return net::COOKIE_PRIORITY_MEDIUM;
case CEF_COOKIE_PRIORITY_HIGH:
return net::COOKIE_PRIORITY_HIGH;
}
}
bool MakeCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie) { bool MakeCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie) {
CefString(&cookie.name).FromString(cc.Name()); CefString(&cookie.name).FromString(cc.Name());
CefString(&cookie.value).FromString(cc.Value()); CefString(&cookie.value).FromString(cc.Value());
@ -189,6 +237,8 @@ bool MakeCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie) {
cookie.has_expires = cc.IsPersistent(); cookie.has_expires = cc.IsPersistent();
if (cookie.has_expires) if (cookie.has_expires)
cef_time_from_basetime(cc.ExpiryDate(), cookie.expires); cef_time_from_basetime(cc.ExpiryDate(), cookie.expires);
cookie.same_site = MakeCefCookieSameSite(cc.SameSite());
cookie.priority = MakeCefCookiePriority(cc.Priority());
return true; return true;
} }
@ -225,6 +275,8 @@ bool MakeCefCookie(const GURL& url,
cookie.has_expires = !cookie_expires.is_null(); cookie.has_expires = !cookie_expires.is_null();
if (cookie.has_expires) if (cookie.has_expires)
cef_time_from_basetime(cookie_expires, cookie.expires); cef_time_from_basetime(cookie_expires, cookie.expires);
cookie.same_site = MakeCefCookieSameSite(pc.SameSite());
cookie.priority = MakeCefCookiePriority(pc.Priority());
return true; return true;
} }

View File

@ -11,6 +11,7 @@
#include "include/internal/cef_types_wrappers.h" #include "include/internal/cef_types_wrappers.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "net/cookies/cookie_constants.h"
namespace net { namespace net {
class CanonicalCookie; class CanonicalCookie;
@ -70,6 +71,9 @@ bool MakeCefCookie(const GURL& url,
const std::string& cookie_line, const std::string& cookie_line,
CefCookie& cookie); CefCookie& cookie);
net::CookieSameSite MakeCookieSameSite(cef_cookie_same_site_t value);
net::CookiePriority MakeCookiePriority(cef_cookie_priority_t value);
} // namespace net_service } // namespace net_service
#endif // CEF_LIBCEF_COMMON_NET_SERVICE_NET_SERVICE_UTIL_H_ #endif // CEF_LIBCEF_COMMON_NET_SERVICE_NET_SERVICE_UTIL_H_

View File

@ -132,6 +132,13 @@ class CefRenderURLRequest::Context
// DCHECK'd in ResourceDispatcherHostImpl::ContinuePendingBeginRequest. // DCHECK'd in ResourceDispatcherHostImpl::ContinuePendingBeginRequest.
resource_request->request_initiator = url::Origin::Create(url); resource_request->request_initiator = url::Origin::Create(url);
if (request_->GetFlags() & UR_FLAG_ALLOW_STORED_CREDENTIALS) {
// Include SameSite cookies.
resource_request->attach_same_site_cookies = true;
resource_request->site_for_cookies =
net::SiteForCookies::FromOrigin(*resource_request->request_initiator);
}
if (resource_request->request_body) { if (resource_request->request_body) {
const auto& elements = *resource_request->request_body->elements(); const auto& elements = *resource_request->request_body->elements();
if (elements.size() > 0) { if (elements.size() > 0) {

View File

@ -247,6 +247,8 @@ void GetCookie(CefRefPtr<CefCookieManager> manager,
EXPECT_EQ(cookie.expires.minute, cookie_read.expires.minute); EXPECT_EQ(cookie.expires.minute, cookie_read.expires.minute);
EXPECT_EQ(cookie.expires.second, cookie_read.expires.second); EXPECT_EQ(cookie.expires.second, cookie_read.expires.second);
EXPECT_EQ(cookie.expires.millisecond, cookie_read.expires.millisecond); EXPECT_EQ(cookie.expires.millisecond, cookie_read.expires.millisecond);
EXPECT_EQ(cookie.same_site, cookie_read.same_site);
EXPECT_EQ(cookie.priority, cookie_read.priority);
} }
// Verify that no cookies exist. If |withUrl| is true it will only check for // Verify that no cookies exist. If |withUrl| is true it will only check for

View File

@ -475,10 +475,7 @@ void VerifyNormalRequest(const RequestRunSettings* settings,
has_send_cookie = true; has_send_cookie = true;
} }
if (settings->expect_send_cookie) EXPECT_EQ(settings->expect_send_cookie, has_send_cookie);
EXPECT_TRUE(has_send_cookie);
else
EXPECT_FALSE(has_send_cookie);
} }
// Populate normal response contents. // Populate normal response contents.