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_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.
///
@ -791,6 +810,16 @@ typedef struct _cef_cookie_t {
///
int has_expires;
cef_time_t expires;
///
// Same site.
///
cef_cookie_same_site_t same_site;
///
// Priority.
///
cef_cookie_priority_t priority;
} cef_cookie_t;
///

View File

@ -851,6 +851,8 @@ struct CefCookieTraits {
target->last_access = src->last_access;
target->has_expires = src->has_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/simple_url_loader.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 {
@ -254,6 +255,23 @@ class CefBrowserURLRequest::Context
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
// correctly below.
auto request_body = resource_request->request_body;

View File

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

View File

@ -620,18 +620,6 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
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 (features::kCalculateNativeWinOcclusion.default_state ==
base::FEATURE_ENABLED_BY_DEFAULT) {

View File

@ -38,6 +38,30 @@ bool GetCookieDomain(const GURL& url,
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
const char kHTTPLocationHeaderName[] = "Location";
@ -177,6 +201,30 @@ net::RedirectInfo MakeRedirectInfo(const network::ResourceRequest& request,
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) {
CefString(&cookie.name).FromString(cc.Name());
CefString(&cookie.value).FromString(cc.Value());
@ -189,6 +237,8 @@ bool MakeCefCookie(const net::CanonicalCookie& cc, CefCookie& cookie) {
cookie.has_expires = cc.IsPersistent();
if (cookie.has_expires)
cef_time_from_basetime(cc.ExpiryDate(), cookie.expires);
cookie.same_site = MakeCefCookieSameSite(cc.SameSite());
cookie.priority = MakeCefCookiePriority(cc.Priority());
return true;
}
@ -225,6 +275,8 @@ bool MakeCefCookie(const GURL& url,
cookie.has_expires = !cookie_expires.is_null();
if (cookie.has_expires)
cef_time_from_basetime(cookie_expires, cookie.expires);
cookie.same_site = MakeCefCookieSameSite(pc.SameSite());
cookie.priority = MakeCefCookiePriority(pc.Priority());
return true;
}

View File

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

View File

@ -132,6 +132,13 @@ class CefRenderURLRequest::Context
// DCHECK'd in ResourceDispatcherHostImpl::ContinuePendingBeginRequest.
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) {
const auto& elements = *resource_request->request_body->elements();
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.second, cookie_read.expires.second);
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

View File

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