Reland "[Cookie Expires/Max-Age Upper Limit] (3) Enable by default"
This reverts commitc8b12486f3
. Reason for revert: Fixing broken bots, underlying change is correct one Original change's description: > Revert "[Cookie Expires/Max-Age Upper Limit] (3) Enable by default" > > This reverts commitcaff7911ae
. > > Reason for revert: Failing multiple bots > > Original change's description: > > [Cookie Expires/Max-Age Upper Limit] (3) Enable by default > > > > This won't be committed until after shipping is approved. > > For now, this is just for vetting. > > > > This CL is a part of a series: > > (1) Add new UMA > > (2) Implement limit behind flag > > (3) Enable by default > > > > Spec: > > https://github.com/httpwg/http-extensions/pull/1732 > > > > Bug: 1264458 > > Change-Id: Idc0469d260c4a5706a9c64feec9af5a0f490d311 > > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3561385 > > Reviewed-by: Christian Dullweber <dullweber@chromium.org> > > Reviewed-by: Clark DuVall <cduvall@chromium.org> > > Auto-Submit: Ari Chivukula <arichiv@chromium.org> > > Reviewed-by: David Roger <droger@chromium.org> > > Reviewed-by: Steven Bingler <bingler@chromium.org> > > Commit-Queue: Ari Chivukula <arichiv@chromium.org> > > Reviewed-by: Kenichi Ishibashi <bashi@chromium.org> > > Cr-Commit-Position: refs/heads/main@{#1003286} > > Bug: 1264458,1325493
> Change-Id: Ia10ffe2f5b6b21a6de3f6bc3a3014510ac3a0e68 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3648321 > Commit-Queue: Lijin Shen <lazzzis@google.com> > Owners-Override: Lijin Shen <lazzzis@google.com> > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> > Cr-Commit-Position: refs/heads/main@{#1003366} Bug: 1264458,1325493
Change-Id: Id9a059fe1c9755420aacc5fb0fc428883259facf Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3645552 Reviewed-by: Kenichi Ishibashi <bashi@chromium.org> Commit-Queue: Christian Dullweber <dullweber@chromium.org> Reviewed-by: Clark DuVall <cduvall@chromium.org> Reviewed-by: Christian Dullweber <dullweber@chromium.org> Auto-Submit: Ari Chivukula <arichiv@chromium.org> Reviewed-by: David Roger <droger@chromium.org> Reviewed-by: Steven Bingler <bingler@chromium.org> Cr-Commit-Position: refs/heads/main@{#1004201}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
a1ff90cab8
commit
aaa5d2b554
chrome/test/data/extensions/api_test/cookies
content/browser/browsing_data
google_apis/gaia
net
base
cookies
third_party/blink/web_tests/external/wpt/cookie-store
weblayer/browser/android/javatests
@ -144,7 +144,13 @@ chrome.test.runTests([
|
||||
chrome.test.assertEq(false, cookie.httpOnly);
|
||||
chrome.test.assertEq('unspecified', cookie.sameSite);
|
||||
chrome.test.assertEq(false, cookie.session);
|
||||
chrome.test.assertEq(TEST_EXPIRATION_DATE, cookie.expirationDate);
|
||||
// Expiration is clamped to 400 days, so we test if it's within a
|
||||
// minute of 400 days from now.
|
||||
const dateDiffInSec = cookie.expirationDate -
|
||||
Math.round(Date.now()/1000);
|
||||
const fourHundredDayInSec = 400 * 24 * 60 * 60;
|
||||
chrome.test.assertTrue(
|
||||
Math.abs(dateDiffInSec - fourHundredDayInSec) < 60);
|
||||
}));
|
||||
}));
|
||||
},
|
||||
|
@ -2,6 +2,9 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Expiration is capped at 400 days in the future, so we use 100 days here.
|
||||
var TEST_EXPIRATION_DATE = Math.round(Date.now() / 1000) + 100 * 24 * 60 * 60;
|
||||
|
||||
// These are the cookies we expect to see along the way.
|
||||
var SET_REMOVE_COOKIE = {
|
||||
name: 'testSetRemove',
|
||||
@ -13,7 +16,7 @@ var SET_REMOVE_COOKIE = {
|
||||
httpOnly: false,
|
||||
sameSite: chrome.cookies.SameSiteStatus.UNSPECIFIED,
|
||||
session: false,
|
||||
expirationDate: 12345678900,
|
||||
expirationDate: TEST_EXPIRATION_DATE,
|
||||
storeId: "0"
|
||||
};
|
||||
|
||||
@ -27,7 +30,7 @@ var OVERWRITE_COOKIE_PRE = {
|
||||
httpOnly: false,
|
||||
sameSite: chrome.cookies.SameSiteStatus.UNSPECIFIED,
|
||||
session: false,
|
||||
expirationDate: 12345678900,
|
||||
expirationDate: TEST_EXPIRATION_DATE,
|
||||
storeId: "0"
|
||||
};
|
||||
|
||||
@ -41,7 +44,7 @@ var OVERWRITE_COOKIE_POST = {
|
||||
httpOnly: false,
|
||||
sameSite: chrome.cookies.SameSiteStatus.UNSPECIFIED,
|
||||
session: false,
|
||||
expirationDate: 12345678900,
|
||||
expirationDate: TEST_EXPIRATION_DATE,
|
||||
storeId: "0"
|
||||
};
|
||||
|
||||
@ -56,7 +59,7 @@ chrome.test.runTests([
|
||||
url: 'http://a.com/path',
|
||||
name: 'testSetRemove',
|
||||
value: '42',
|
||||
expirationDate: 12345678900
|
||||
expirationDate: TEST_EXPIRATION_DATE
|
||||
});
|
||||
},
|
||||
function testRemove() {
|
||||
@ -80,7 +83,7 @@ chrome.test.runTests([
|
||||
url: 'http://a.com/path',
|
||||
name: 'testOverwrite',
|
||||
value: '42',
|
||||
expirationDate: 12345678900
|
||||
expirationDate: TEST_EXPIRATION_DATE
|
||||
});
|
||||
},
|
||||
function overwriteSecondSet() {
|
||||
@ -109,7 +112,7 @@ chrome.test.runTests([
|
||||
url: 'http://a.com/path',
|
||||
name: 'testOverwrite',
|
||||
value: '43',
|
||||
expirationDate: 12345678900
|
||||
expirationDate: TEST_EXPIRATION_DATE
|
||||
});
|
||||
},
|
||||
function overwriteExpired() {
|
||||
|
@ -2,6 +2,9 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Expiration is capped at 400 days in the future, so we use 100 days here.
|
||||
var TEST_EXPIRATION_DATE = Math.round(Date.now() / 1000) + 100 * 24 * 60 * 60;
|
||||
|
||||
// This test verifies that the cookies have the correct store Id in spanning
|
||||
// split mode.
|
||||
var SET_REMOVE_COOKIE = {
|
||||
@ -14,7 +17,7 @@ var SET_REMOVE_COOKIE = {
|
||||
httpOnly: false,
|
||||
sameSite: chrome.cookies.SameSiteStatus.UNSPECIFIED,
|
||||
session: false,
|
||||
expirationDate: 12345678900,
|
||||
expirationDate: TEST_EXPIRATION_DATE,
|
||||
storeId: '1'
|
||||
};
|
||||
|
||||
@ -29,7 +32,7 @@ chrome.test.runTests([
|
||||
url: 'http://a.com/path',
|
||||
name: 'testSetRemove',
|
||||
value: '42',
|
||||
expirationDate: 12345678900,
|
||||
expirationDate: TEST_EXPIRATION_DATE,
|
||||
storeId: '1'
|
||||
});
|
||||
},
|
||||
|
@ -257,8 +257,8 @@ TEST_F(SameSiteDataRemoverImplTest, TestCookieRemovalUnaffectedByParameters) {
|
||||
result_out = false;
|
||||
auto cookie2 = net::CanonicalCookie::CreateUnsafeCookieForTesting(
|
||||
"TestCookie2", "10", "gmail.google.com", "/", base::Time(),
|
||||
base::Time::Max(), base::Time(), base::Time(), false, true,
|
||||
net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_HIGH, false);
|
||||
base::Time::Now() + base::Days(100), base::Time(), base::Time(), false,
|
||||
true, net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_HIGH, false);
|
||||
cookie_manager->SetCanonicalCookie(
|
||||
*cookie2, net::cookie_util::SimulatedCookieSource(*cookie2, "https"),
|
||||
options, base::BindLambdaForTesting([&](net::CookieAccessResult result) {
|
||||
|
@ -105,8 +105,14 @@ void OAuthMultiloginResult::TryParseCookiesFromValue(base::Value* json_value) {
|
||||
const std::string* same_site = cookie.FindStringKey("sameSite");
|
||||
const std::string* same_party = cookie.FindStringKey("sameParty");
|
||||
|
||||
base::TimeDelta before_expiration =
|
||||
base::Seconds(expiration_delta.value_or(0.0));
|
||||
base::Time now = base::Time::Now();
|
||||
// TODO(crbug.com/1264458) If CreateSanitizedCookie were used below, this
|
||||
// wouldn't be needed and ValidateAndAdjustExpiryDate could be moved back
|
||||
// into anon namespace instead of being exposed as a static function.
|
||||
// Alternatly, if we were sure GAIA cookies wouldn't try to expire more
|
||||
// than 400 days in the future we wouldn't need this either.
|
||||
base::Time expiration = net::CanonicalCookie::ValidateAndAdjustExpiryDate(
|
||||
now + base::Seconds(expiration_delta.value_or(0.0)), now);
|
||||
std::string cookie_domain = domain ? *domain : "";
|
||||
std::string cookie_host = host ? *host : "";
|
||||
if (cookie_domain.empty() && !cookie_host.empty() &&
|
||||
@ -127,10 +133,8 @@ void OAuthMultiloginResult::TryParseCookiesFromValue(base::Value* json_value) {
|
||||
std::unique_ptr<net::CanonicalCookie> new_cookie =
|
||||
net::CanonicalCookie::FromStorage(
|
||||
name ? *name : "", value ? *value : "", cookie_domain,
|
||||
path ? *path : "", /*creation=*/base::Time::Now(),
|
||||
base::Time::Now() + before_expiration,
|
||||
/*last_access=*/base::Time::Now(),
|
||||
/*last_update=*/base::Time::Now(), is_secure.value_or(true),
|
||||
path ? *path : "", /*creation=*/now, expiration,
|
||||
/*last_access=*/now, /*last_update=*/now, is_secure.value_or(true),
|
||||
is_http_only.value_or(true), samesite_mode,
|
||||
net::StringToCookiePriority(priority ? *priority : "medium"),
|
||||
same_party_bool, /*partition_key=*/absl::nullopt,
|
||||
|
@ -91,7 +91,7 @@ TEST(OAuthMultiloginResultTest, TryParseCookiesFromValue) {
|
||||
result.TryParseCookiesFromValue(dictionary_value.get());
|
||||
|
||||
base::Time time_now = base::Time::Now();
|
||||
base::Time expiration_time = (time_now + base::Seconds(63070000.));
|
||||
base::Time expiration_time = (time_now + base::Seconds(34560000.));
|
||||
double now = time_now.ToDoubleT();
|
||||
double expiration = expiration_time.ToDoubleT();
|
||||
const std::vector<CanonicalCookie> cookies = {
|
||||
|
@ -291,7 +291,7 @@ const base::Feature kSandboxHttpCache("SandboxHttpCache",
|
||||
|
||||
const base::Feature kClampCookieExpiryTo400Days(
|
||||
"ClampCookieExpiryTo400Days",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
|
||||
#if BUILDFLAG(IS_ANDROID)
|
||||
const base::Feature kStaticKeyPinningEnforcement(
|
||||
|
@ -359,27 +359,6 @@ bool HasValidHostPrefixAttributes(const GURL& url,
|
||||
return domain.empty() || (url.HostIsIPAddress() && url.host() == domain);
|
||||
}
|
||||
|
||||
// Per rfc6265bis the maximum expiry date is no further than 400 days in the
|
||||
// future. Clamping only occurs when kClampCookieExpiryTo400Days is enabled.
|
||||
base::Time ValidateAndAdjustExpiryDate(const base::Time& expiry_date,
|
||||
const base::Time& creation_date) {
|
||||
if (expiry_date.is_null())
|
||||
return expiry_date;
|
||||
base::Time fixed_creation_date = creation_date;
|
||||
if (fixed_creation_date.is_null()) {
|
||||
// TODO(crbug.com/1264458): This shouldn't be necessary, let's examine
|
||||
// where creation_date is null but expiry_date isn't and figure out
|
||||
// what's happening. This blocks the launch until resolved.
|
||||
fixed_creation_date = base::Time::Now();
|
||||
}
|
||||
if (base::FeatureList::IsEnabled(features::kClampCookieExpiryTo400Days)) {
|
||||
base::Time maximum_expiry_date = fixed_creation_date + base::Days(400);
|
||||
if (expiry_date > maximum_expiry_date)
|
||||
return maximum_expiry_date;
|
||||
}
|
||||
return expiry_date;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CookieAccessParams::CookieAccessParams(CookieAccessSemantics access_semantics,
|
||||
@ -527,6 +506,32 @@ Time CanonicalCookie::ParseExpiration(const ParsedCookie& pc,
|
||||
return Time();
|
||||
}
|
||||
|
||||
// static
|
||||
base::Time CanonicalCookie::ValidateAndAdjustExpiryDate(
|
||||
const base::Time& expiry_date,
|
||||
const base::Time& creation_date) {
|
||||
if (expiry_date.is_null())
|
||||
return expiry_date;
|
||||
base::Time fixed_creation_date = creation_date;
|
||||
if (fixed_creation_date.is_null()) {
|
||||
// TODO(crbug.com/1264458): Push this logic into
|
||||
// CanonicalCookie::CreateSanitizedCookie. The four sites that call it
|
||||
// with a null `creation_date` (CanonicalCookie::Create cannot be called
|
||||
// this way) are:
|
||||
// * GaiaCookieManagerService::ForceOnCookieChangeProcessing
|
||||
// * CookiesSetFunction::Run
|
||||
// * cookie_store.cc::ToCanonicalCookie
|
||||
// * network_handler.cc::MakeCookieFromProtocolValues
|
||||
fixed_creation_date = base::Time::Now();
|
||||
}
|
||||
if (base::FeatureList::IsEnabled(features::kClampCookieExpiryTo400Days)) {
|
||||
base::Time maximum_expiry_date = fixed_creation_date + base::Days(400);
|
||||
if (expiry_date > maximum_expiry_date)
|
||||
return maximum_expiry_date;
|
||||
}
|
||||
return expiry_date;
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<CanonicalCookie> CanonicalCookie::Create(
|
||||
const GURL& url,
|
||||
@ -1449,6 +1454,12 @@ bool CanonicalCookie::IsCanonical() const {
|
||||
// would fail this check. Note that we still don't want to enforce length
|
||||
// checks on domain or path for the reason stated above.
|
||||
|
||||
// TODO(crbug.com/1264458): Eventually we should push this logic into
|
||||
// IsCanonicalForFromStorage, but for now we allow cookies already stored with
|
||||
// high expiration dates to be retrieved.
|
||||
if (ValidateAndAdjustExpiryDate(expiry_date_, creation_date_) != expiry_date_)
|
||||
return false;
|
||||
|
||||
return IsCanonicalForFromStorage();
|
||||
}
|
||||
|
||||
|
@ -367,6 +367,12 @@ class NET_EXPORT CanonicalCookie {
|
||||
const base::Time& current,
|
||||
const base::Time& server_time);
|
||||
|
||||
// Per rfc6265bis the maximum expiry date is no further than 400 days in the
|
||||
// future. Clamping only occurs when kClampCookieExpiryTo400Days is enabled.
|
||||
static base::Time ValidateAndAdjustExpiryDate(
|
||||
const base::Time& expiry_date,
|
||||
const base::Time& creation_date);
|
||||
|
||||
// Cookie ordering methods.
|
||||
|
||||
// Returns true if the cookie is less than |other|, considering only name,
|
||||
|
@ -49,6 +49,9 @@ using testing::Eq;
|
||||
using testing::Not;
|
||||
using testing::Property;
|
||||
|
||||
// Tests which use this class verify the expiry date clamping behavior when
|
||||
// kClampCookieExpiryTo400Days is enabled. This caps expiry dates on new/updated
|
||||
// cookies to max of 400 days, but does not affect previously stored cookies.
|
||||
class CanonicalCookieWithClampingTest
|
||||
: public testing::Test,
|
||||
public testing::WithParamInterface<bool> {
|
||||
@ -672,6 +675,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
|
||||
EXPECT_TRUE(cookie->IsPersistent());
|
||||
EXPECT_FALSE(cookie->IsExpired(creation_time));
|
||||
EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Max-age with expires (max-age should take precedence).
|
||||
cookie = CanonicalCookie::Create(
|
||||
@ -681,6 +685,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
|
||||
EXPECT_TRUE(cookie->IsPersistent());
|
||||
EXPECT_FALSE(cookie->IsExpired(creation_time));
|
||||
EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Max-age=0 should create an expired cookie with expiry equal to the earliest
|
||||
// representable time.
|
||||
@ -691,6 +696,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
|
||||
EXPECT_TRUE(cookie->IsPersistent());
|
||||
EXPECT_TRUE(cookie->IsExpired(creation_time));
|
||||
EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Negative max-age should create an expired cookie with expiry equal to the
|
||||
// earliest representable time.
|
||||
@ -701,6 +707,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
|
||||
EXPECT_TRUE(cookie->IsPersistent());
|
||||
EXPECT_TRUE(cookie->IsExpired(creation_time));
|
||||
EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Max-age with whitespace (should be trimmed out).
|
||||
cookie = CanonicalCookie::Create(url, "A=1; max-age = 60 ; Secure",
|
||||
@ -710,6 +717,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
|
||||
EXPECT_TRUE(cookie->IsPersistent());
|
||||
EXPECT_FALSE(cookie->IsExpired(creation_time));
|
||||
EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Max-age with non-integer should be ignored.
|
||||
cookie = CanonicalCookie::Create(url, "A=1; max-age=abcd", creation_time,
|
||||
@ -718,6 +726,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
|
||||
EXPECT_TRUE(cookie.get());
|
||||
EXPECT_FALSE(cookie->IsPersistent());
|
||||
EXPECT_FALSE(cookie->IsExpired(creation_time));
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Overflow max-age should be clipped.
|
||||
cookie = CanonicalCookie::Create(url,
|
||||
@ -735,6 +744,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
|
||||
} else {
|
||||
EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
|
||||
}
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Underflow max-age should be clipped.
|
||||
cookie = CanonicalCookie::Create(url,
|
||||
@ -748,6 +758,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
|
||||
EXPECT_TRUE(cookie->IsPersistent());
|
||||
EXPECT_TRUE(cookie->IsExpired(creation_time));
|
||||
EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
}
|
||||
|
||||
TEST_P(CanonicalCookieWithClampingTest, CreateWithExpires) {
|
||||
@ -765,6 +776,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithExpires) {
|
||||
EXPECT_TRUE(cookie->IsExpired(creation_time));
|
||||
EXPECT_TRUE((past_date - cookie->ExpiryDate()).magnitude() <
|
||||
base::Seconds(1));
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Expires in the future
|
||||
base::Time future_date = base::Time::Now() + base::Days(10);
|
||||
@ -776,6 +788,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithExpires) {
|
||||
EXPECT_FALSE(cookie->IsExpired(creation_time));
|
||||
EXPECT_TRUE((future_date - cookie->ExpiryDate()).magnitude() <
|
||||
base::Seconds(1));
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Expires in the far future
|
||||
future_date = base::Time::Now() + base::Days(800);
|
||||
@ -793,6 +806,7 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithExpires) {
|
||||
EXPECT_TRUE((future_date - cookie->ExpiryDate()).magnitude() <
|
||||
base::Seconds(1));
|
||||
}
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
|
||||
// Expires in the far future using CreateUnsafeCookieForTesting.
|
||||
cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
|
||||
@ -805,6 +819,11 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithExpires) {
|
||||
EXPECT_FALSE(cookie->IsExpired(creation_time));
|
||||
EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
|
||||
EXPECT_EQ(base::Time(), cookie->LastUpdateDate());
|
||||
if (IsClampCookieExpiryTo400DaysEnabled()) {
|
||||
EXPECT_FALSE(cookie->IsCanonical());
|
||||
} else {
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
}
|
||||
|
||||
// Expires in the far future using FromStorage.
|
||||
cookie = CanonicalCookie::FromStorage(
|
||||
@ -818,6 +837,11 @@ TEST_P(CanonicalCookieWithClampingTest, CreateWithExpires) {
|
||||
EXPECT_FALSE(cookie->IsExpired(creation_time));
|
||||
EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
|
||||
EXPECT_EQ(base::Time(), cookie->LastUpdateDate());
|
||||
if (IsClampCookieExpiryTo400DaysEnabled()) {
|
||||
EXPECT_FALSE(cookie->IsCanonical());
|
||||
} else {
|
||||
EXPECT_TRUE(cookie->IsCanonical());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CanonicalCookieTest, EmptyExpiry) {
|
||||
|
@ -205,7 +205,7 @@ std::unique_ptr<CookieMonster> CreateMonsterFromStoreForGC(
|
||||
int num_old_non_secure_cookies,
|
||||
int days_old) {
|
||||
base::Time current(base::Time::Now());
|
||||
base::Time past_creation(base::Time::Now() - base::Days(1000));
|
||||
base::Time past_creation(base::Time::Now() - base::Days(100));
|
||||
scoped_refptr<MockSimplePersistentCookieStore> store(
|
||||
new MockSimplePersistentCookieStore);
|
||||
int total_cookies = num_secure_cookies + num_non_secure_cookies;
|
||||
|
@ -32,9 +32,11 @@
|
||||
#include "base/test/bind.h"
|
||||
#include "base/test/metrics/histogram_tester.h"
|
||||
#include "base/test/mock_callback.h"
|
||||
#include "base/test/scoped_feature_list.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "base/time/time.h"
|
||||
#include "net/base/features.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
#include "net/cookies/canonical_cookie_test_helpers.h"
|
||||
#include "net/cookies/cookie_change_dispatcher.h"
|
||||
@ -81,6 +83,26 @@ MATCHER_P2(MatchesCookieNameDomain, name, domain, "") {
|
||||
arg, result_listener);
|
||||
}
|
||||
|
||||
MATCHER_P4(MatchesCookieNameValueCreationExpiry,
|
||||
name,
|
||||
value,
|
||||
creation,
|
||||
expiry,
|
||||
"") {
|
||||
return testing::ExplainMatchResult(
|
||||
testing::AllOf(
|
||||
testing::Property(&net::CanonicalCookie::Name, name),
|
||||
testing::Property(&net::CanonicalCookie::Value, value),
|
||||
testing::Property(&net::CanonicalCookie::CreationDate, creation),
|
||||
// We need a margin of error when testing the ExpiryDate as, if
|
||||
// clamped, it is set relative to the current time.
|
||||
testing::Property(&net::CanonicalCookie::ExpiryDate,
|
||||
testing::Gt(expiry - base::Minutes(1))),
|
||||
testing::Property(&net::CanonicalCookie::ExpiryDate,
|
||||
testing::Lt(expiry + base::Minutes(1)))),
|
||||
arg, result_listener);
|
||||
}
|
||||
|
||||
const char kTopLevelDomainPlus1[] = "http://www.harvard.edu";
|
||||
const char kTopLevelDomainPlus2[] = "http://www.math.harvard.edu";
|
||||
const char kTopLevelDomainPlus2Secure[] = "https://www.math.harvard.edu";
|
||||
@ -5487,4 +5509,262 @@ TEST_F(CookieMonsterTest, ConvertPartitionedCookiesToUnpartitioned) {
|
||||
EXPECT_TRUE(cookies[0].IsPartitioned());
|
||||
}
|
||||
|
||||
// Tests which use this class verify the expiry date clamping behavior when
|
||||
// kClampCookieExpiryTo400Days is enabled. This caps expiry dates on new/updated
|
||||
// cookies to max of 400 days, but does not affect previously stored cookies.
|
||||
class CookieMonsterWithClampingTest : public CookieMonsterTest,
|
||||
public testing::WithParamInterface<bool> {
|
||||
public:
|
||||
CookieMonsterWithClampingTest() {
|
||||
scoped_feature_list_.InitWithFeatureState(
|
||||
features::kClampCookieExpiryTo400Days,
|
||||
IsClampCookieExpiryTo400DaysEnabled());
|
||||
}
|
||||
bool IsClampCookieExpiryTo400DaysEnabled() { return GetParam(); }
|
||||
|
||||
private:
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(/* no label */,
|
||||
CookieMonsterWithClampingTest,
|
||||
testing::Bool());
|
||||
|
||||
// This test sets a cookie (only checked using IsCanonicalForFromStorage)
|
||||
// that's 300 days old and expires in 800 days. It checks that this cookie was
|
||||
// stored, and then update it. It checks that the updated cookie has the
|
||||
// creation and expiry dates expected given whether or not clamping is on.
|
||||
TEST_P(CookieMonsterWithClampingTest,
|
||||
FromStorageCookieCreated300DaysAgoThenUpdatedNow) {
|
||||
scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
|
||||
auto cookie_monster = std::make_unique<CookieMonster>(
|
||||
store.get(), net::NetLog::Get(), kFirstPartySetsDefault);
|
||||
cookie_monster->SetPersistSessionCookies(true);
|
||||
EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
|
||||
|
||||
// Bypass IsCanonical and store a 300 day old cookie to bypass clamping.
|
||||
base::Time original_creation = base::Time::Now() - base::Days(300);
|
||||
base::Time original_expiry = original_creation + base::Days(800);
|
||||
CookieList list;
|
||||
list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
|
||||
"A", "B", "." + https_www_foo_.url().host(), "/", original_creation,
|
||||
original_expiry, base::Time(), base::Time(), true, false,
|
||||
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true));
|
||||
EXPECT_TRUE(SetAllCookies(cookie_monster.get(), list));
|
||||
|
||||
// Verify the cookie exists and was not clamped, even if clamping is on.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, original_expiry)));
|
||||
|
||||
// Update the cookie without bypassing clamping.
|
||||
base::Time new_creation = base::Time::Now();
|
||||
base::Time new_expiry = new_creation + base::Days(800);
|
||||
EXPECT_TRUE(SetCanonicalCookie(
|
||||
cookie_monster.get(),
|
||||
CanonicalCookie::CreateSanitizedCookie(
|
||||
https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
|
||||
new_creation, new_expiry, base::Time(), true, false,
|
||||
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true,
|
||||
absl::nullopt),
|
||||
https_www_foo_.url(), false));
|
||||
|
||||
if (IsClampCookieExpiryTo400DaysEnabled()) {
|
||||
// The clamped update should retain the original creation date, but have
|
||||
// a clamped expiry date.
|
||||
EXPECT_THAT(
|
||||
GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, new_creation + base::Days(400))));
|
||||
} else {
|
||||
// The unclamped update should retain the original creation date and have
|
||||
// an unclamped expiry date.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, new_expiry)));
|
||||
}
|
||||
}
|
||||
|
||||
// This test sets a cookie (only checked using IsCanonicalForFromStorage)
|
||||
// that's 500 days old and expires in 800 days. It checks that this cookie was
|
||||
// stored, and then update it. It checks that the updated cookie has the
|
||||
// creation and expiry dates expected given whether or not clamping is on.
|
||||
TEST_P(CookieMonsterWithClampingTest,
|
||||
FromStorageCookieCreated500DaysAgoThenUpdatedNow) {
|
||||
scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
|
||||
auto cookie_monster = std::make_unique<CookieMonster>(
|
||||
store.get(), net::NetLog::Get(), kFirstPartySetsDefault);
|
||||
cookie_monster->SetPersistSessionCookies(true);
|
||||
EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
|
||||
|
||||
// Bypass IsCanonical and store a 500 day old cookie to bypass clamping.
|
||||
base::Time original_creation = base::Time::Now() - base::Days(500);
|
||||
base::Time original_expiry = original_creation + base::Days(800);
|
||||
CookieList list;
|
||||
list.push_back(*CanonicalCookie::CreateUnsafeCookieForTesting(
|
||||
"A", "B", "." + https_www_foo_.url().host(), "/", original_creation,
|
||||
original_expiry, base::Time(), base::Time(), true, false,
|
||||
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true));
|
||||
EXPECT_TRUE(SetAllCookies(cookie_monster.get(), list));
|
||||
|
||||
// Verify the cookie exists and was not clamped, even if clamping is on.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, original_expiry)));
|
||||
|
||||
// Update the cookie without bypassing clamping.
|
||||
base::Time new_creation = base::Time::Now();
|
||||
base::Time new_expiry = new_creation + base::Days(800);
|
||||
EXPECT_TRUE(SetCanonicalCookie(
|
||||
cookie_monster.get(),
|
||||
CanonicalCookie::CreateSanitizedCookie(
|
||||
https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
|
||||
new_creation, new_expiry, base::Time(), true, false,
|
||||
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true,
|
||||
absl::nullopt),
|
||||
https_www_foo_.url(), false));
|
||||
|
||||
if (IsClampCookieExpiryTo400DaysEnabled()) {
|
||||
// The clamped update should retain the original creation date, but have
|
||||
// a clamped expiry date.
|
||||
EXPECT_THAT(
|
||||
GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, new_creation + base::Days(400))));
|
||||
} else {
|
||||
// The unclamped update should retain the original creation date and have
|
||||
// an unclamped expiry date.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, new_expiry)));
|
||||
}
|
||||
}
|
||||
|
||||
// This test sets a cookie (checked using IsCanonical) that's 300 days old and
|
||||
// expires in 800 days. It checks that this cookie was stored, and then update
|
||||
// it. It checks that the updated cookie has the creation and expiry dates
|
||||
// expected given whether or not clamping is on.
|
||||
TEST_P(CookieMonsterWithClampingTest,
|
||||
SanitizedCookieCreated300DaysAgoThenUpdatedNow) {
|
||||
scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
|
||||
auto cookie_monster = std::make_unique<CookieMonster>(
|
||||
store.get(), net::NetLog::Get(), kFirstPartySetsDefault);
|
||||
cookie_monster->SetPersistSessionCookies(true);
|
||||
EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
|
||||
|
||||
// Store a 300 day old cookie without bypassing clamping.
|
||||
base::Time original_creation = base::Time::Now() - base::Days(300);
|
||||
base::Time original_expiry = original_creation + base::Days(800);
|
||||
EXPECT_TRUE(SetCanonicalCookie(
|
||||
cookie_monster.get(),
|
||||
CanonicalCookie::CreateSanitizedCookie(
|
||||
https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
|
||||
original_creation, original_expiry, base::Time(), true, false,
|
||||
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true,
|
||||
absl::nullopt),
|
||||
https_www_foo_.url(), false));
|
||||
|
||||
if (IsClampCookieExpiryTo400DaysEnabled()) {
|
||||
// The clamped set should have a clamped expiry date.
|
||||
EXPECT_THAT(
|
||||
GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, original_creation + base::Days(400))));
|
||||
} else {
|
||||
// The unclamped set should have an unclamped expiry date.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, original_expiry)));
|
||||
}
|
||||
|
||||
// Update the cookie without bypassing clamping.
|
||||
base::Time new_creation = base::Time::Now();
|
||||
base::Time new_expiry = new_creation + base::Days(800);
|
||||
EXPECT_TRUE(SetCanonicalCookie(
|
||||
cookie_monster.get(),
|
||||
CanonicalCookie::CreateSanitizedCookie(
|
||||
https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
|
||||
new_creation, new_expiry, base::Time(), true, false,
|
||||
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true,
|
||||
absl::nullopt),
|
||||
https_www_foo_.url(), false));
|
||||
|
||||
if (IsClampCookieExpiryTo400DaysEnabled()) {
|
||||
// The clamped update should retain the original creation date, but have
|
||||
// a clamped expiry date.
|
||||
EXPECT_THAT(
|
||||
GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, new_creation + base::Days(400))));
|
||||
} else {
|
||||
// The unclamped update should retain the original creation date and have
|
||||
// an unclamped expiry date.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, new_expiry)));
|
||||
}
|
||||
}
|
||||
|
||||
// This test sets a cookie (checked using IsCanonical) that's 500 days old and
|
||||
// expires in 800 days. It checks that this cookie was stored, and then update
|
||||
// it. It checks that the updated cookie has the creation and expiry dates
|
||||
// expected given whether or not clamping is on.
|
||||
TEST_P(CookieMonsterWithClampingTest,
|
||||
SanitizedCookieCreated500DaysAgoThenUpdatedNow) {
|
||||
scoped_refptr<FlushablePersistentStore> store(new FlushablePersistentStore());
|
||||
auto cookie_monster = std::make_unique<CookieMonster>(
|
||||
store.get(), net::NetLog::Get(), kFirstPartySetsDefault);
|
||||
cookie_monster->SetPersistSessionCookies(true);
|
||||
EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
|
||||
|
||||
// Store a 500 day old cookie without bypassing clamping.
|
||||
base::Time original_creation = base::Time::Now() - base::Days(500);
|
||||
base::Time original_expiry = original_creation + base::Days(800);
|
||||
EXPECT_TRUE(SetCanonicalCookie(
|
||||
cookie_monster.get(),
|
||||
CanonicalCookie::CreateSanitizedCookie(
|
||||
https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
|
||||
original_creation, original_expiry, base::Time(), true, false,
|
||||
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true,
|
||||
absl::nullopt),
|
||||
https_www_foo_.url(), false));
|
||||
|
||||
if (IsClampCookieExpiryTo400DaysEnabled()) {
|
||||
// The clamped set should result in no stored cookie.
|
||||
EXPECT_TRUE(GetAllCookies(cookie_monster.get()).empty());
|
||||
} else {
|
||||
// The unclamped set should have an unclamped expiry date.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, original_expiry)));
|
||||
}
|
||||
|
||||
// Update the cookie without bypassing clamping.
|
||||
base::Time new_creation = base::Time::Now();
|
||||
base::Time new_expiry = new_creation + base::Days(800);
|
||||
EXPECT_TRUE(SetCanonicalCookie(
|
||||
cookie_monster.get(),
|
||||
CanonicalCookie::CreateSanitizedCookie(
|
||||
https_www_foo_.url(), "A", "B", https_www_foo_.url().host(), "/",
|
||||
new_creation, new_expiry, base::Time(), true, false,
|
||||
CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true,
|
||||
absl::nullopt),
|
||||
https_www_foo_.url(), false));
|
||||
|
||||
// The clamped one has the new creation date as the old cookie was expired.
|
||||
if (IsClampCookieExpiryTo400DaysEnabled()) {
|
||||
// The clamped update was really a set as the old cookie expired, so it has
|
||||
// the new creation date and a clamped expiry date.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", new_creation, new_creation + base::Days(400))));
|
||||
} else {
|
||||
// The unclamped update should retain the original creation date and have
|
||||
// an unclamped expiry date.
|
||||
EXPECT_THAT(GetAllCookies(cookie_monster.get()),
|
||||
ElementsAre(MatchesCookieNameValueCreationExpiry(
|
||||
"A", "B", original_creation, new_expiry)));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
|
6
third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.js
vendored
6
third_party/blink/web_tests/external/wpt/cookie-store/cookieListItem_attributes.https.any.js
vendored
@ -6,7 +6,9 @@
|
||||
const kCurrentHostname = (new URL(self.location.href)).hostname;
|
||||
|
||||
const kOneDay = 24 * 60 * 60 * 1000;
|
||||
const kFourHundredDays = 400 * kOneDay;
|
||||
const kTenYears = 10 * 365 * kOneDay;
|
||||
const kFourHundredDaysFromNow = Date.now() + kFourHundredDays;
|
||||
const kTenYearsFromNow = Date.now() + kTenYears;
|
||||
|
||||
const kCookieListItemKeys =
|
||||
@ -68,7 +70,7 @@ promise_test(async testCase => {
|
||||
assert_equals(cookie.value, 'cookie-value');
|
||||
assert_equals(cookie.domain, null);
|
||||
assert_equals(cookie.path, '/');
|
||||
assert_approx_equals(cookie.expires, kTenYearsFromNow, kOneDay);
|
||||
assert_approx_equals(cookie.expires, kFourHundredDaysFromNow, kOneDay);
|
||||
assert_equals(cookie.secure, true);
|
||||
assert_equals(cookie.sameSite, 'strict');
|
||||
const itemKeys = Object.keys(cookie);
|
||||
@ -91,7 +93,7 @@ promise_test(async testCase => {
|
||||
assert_equals(cookie.value, 'cookie-value');
|
||||
assert_equals(cookie.domain, null);
|
||||
assert_equals(cookie.path, '/');
|
||||
assert_approx_equals(cookie.expires, kTenYearsFromNow, kOneDay);
|
||||
assert_approx_equals(cookie.expires, kFourHundredDaysFromNow, kOneDay);
|
||||
assert_equals(cookie.secure, true);
|
||||
}, 'CookieListItem - cookieStore.set with expires set to a Date 10 ' +
|
||||
'years in the future');
|
||||
|
@ -5,7 +5,7 @@
|
||||
# with versions less than or equal to $VERSION of the implementation.
|
||||
#
|
||||
# These lines are not comments! They define the set of known tags and other information.
|
||||
# tags: [ client_lte_91 client_lte_94 client_lte_95 impl_lte_95 client_lte_98 impl_lte_98 ]
|
||||
# tags: [ client_lte_91 client_lte_94 client_lte_95 impl_lte_95 client_lte_98 impl_lte_98 client_lte_103 ]
|
||||
# 'all' disables the test from any skew test.
|
||||
# tags: [ all ]
|
||||
# results: [ Skip ]
|
||||
@ -111,3 +111,6 @@ crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigatio
|
||||
crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testUserClicksLinkToPageWithExternalIntentLaunchedViaOnLoad [ Skip ]
|
||||
crbug.com/1278017 [ client_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testAvoidDisambiguationDialog [ Skip ]
|
||||
crbug.com/1278017 [ impl_lte_98 ] org.chromium.weblayer.test.ExternalNavigationTest#testAvoidDisambiguationDialog [ Skip ]
|
||||
|
||||
# In 104 we started to cap maximum cookie expiration date
|
||||
crbug.com/1264458 [ client_lte_103 ] org.chromium.weblayer.test.CookieManagerTest#testGetResponseCookiesAllAttributes [ Skip ]
|
||||
|
@ -134,10 +134,14 @@ public class CookieManagerTest {
|
||||
Assert.assertTrue(getResponseCookies().isEmpty());
|
||||
|
||||
// Setting a cookie with all attributes should return the same cookie.
|
||||
String cookie = "foo=bar; path=/; domain=127.0.0.1; expires=Thu, 15 Jul 2032 00:00:01 GMT; "
|
||||
+ "secure; httponly; samesite=lax; priority=high; sameparty";
|
||||
Assert.assertTrue(setCookie(cookie));
|
||||
Assert.assertThat(getResponseCookies(), Matchers.containsInAnyOrder(cookie));
|
||||
String cookieStart = "foo=bar; path=/; domain=127.0.0.1; expires=";
|
||||
String cookieExpires = "Thu, 15 Jul 2032 00:00:01 GMT";
|
||||
String cookieEnd = "; secure; httponly; samesite=lax; priority=high; sameparty";
|
||||
Assert.assertTrue(setCookie(cookieStart + cookieExpires + cookieEnd));
|
||||
List<String> cookiesSet = getResponseCookies();
|
||||
Assert.assertEquals(cookiesSet.size(), 1);
|
||||
// Expiration is clamped to 400 days, so for now we just test that some date was sent back.
|
||||
Assert.assertTrue(cookiesSet.get(0).matches(cookieStart + "[A-Za-z0-9 ,:]*" + cookieEnd));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user