0

Reland "[Cookie Expires/Max-Age Upper Limit] (3) Enable by default"

This reverts commit c8b12486f3.

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 commit caff7911ae.
>
> 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:
Ari Chivukula
2022-05-17 11:41:52 +00:00
committed by Chromium LUCI CQ
parent a1ff90cab8
commit aaa5d2b554
15 changed files with 394 additions and 48 deletions
chrome/test/data/extensions/api_test/cookies
api
events
events_spanning
content/browser/browsing_data
google_apis/gaia
net
third_party/blink/web_tests/external/wpt/cookie-store
weblayer/browser/android/javatests
skew
src
org
chromium

@ -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,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