mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Backed out 5 changesets (bug 1923663, bug 1922193) for causing cookie parsing crashes.
Backed out changeset f70a3f184cef (bug 1923663) Backed out changeset a7114c76e107 (bug 1923663) Backed out changeset 01c2f8a4572f (bug 1922193) Backed out changeset 6ca20b512745 (bug 1922193) Backed out changeset fb747408813c (bug 1922193)
This commit is contained in:
parent
7e1a376bd5
commit
5ea2ca1ea1
@ -74,8 +74,7 @@ var SessionCookiesInternal = {
|
||||
expiry,
|
||||
cookie.originAttributes || {},
|
||||
cookie.sameSite || Ci.nsICookie.SAMESITE_NONE,
|
||||
cookie.schemeMap || Ci.nsICookie.SCHEME_HTTPS,
|
||||
cookie.isPartitioned
|
||||
cookie.schemeMap || Ci.nsICookie.SCHEME_HTTPS
|
||||
);
|
||||
} catch (ex) {
|
||||
console.error(
|
||||
@ -257,10 +256,6 @@ var CookieStore = {
|
||||
jscookie.schemeMap = cookie.schemeMap;
|
||||
}
|
||||
|
||||
if (cookie.isPartitioned) {
|
||||
jscookie.isPartitioned = true;
|
||||
}
|
||||
|
||||
this._entries.set(this._getKeyForCookie(cookie), jscookie);
|
||||
},
|
||||
|
||||
|
@ -12381,21 +12381,7 @@
|
||||
# Whether to support CHIPS(Cookies Having Independent Partitioned State).
|
||||
- name: network.cookie.CHIPS.enabled
|
||||
type: RelaxedAtomicBool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Updated to match the target count when we migrate the unpartitioned CHIPS
|
||||
# cookies to their first-party partition.
|
||||
- name: network.cookie.CHIPS.lastMigrateDatabase
|
||||
type: RelaxedAtomicUint32
|
||||
value: 0
|
||||
mirror: always
|
||||
|
||||
# Used to increase the number of times we want to have migrated the database.
|
||||
# This lets us remotely perform a database migration with Nimbus.
|
||||
- name: network.cookie.CHIPS.migrateDatabaseTarget
|
||||
type: RelaxedAtomicUint32
|
||||
value: 1
|
||||
value: @IS_NIGHTLY_BUILD@
|
||||
mirror: always
|
||||
|
||||
# Stale threshold for cookies in seconds.
|
||||
|
@ -545,39 +545,6 @@ bool CookieCommons::ShouldIncludeCrossSiteCookie(int32_t aSameSiteAttr,
|
||||
return aSameSiteAttr == nsICookie::SAMESITE_NONE;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CookieCommons::IsFirstPartyPartitionedCookieWithoutCHIPS(
|
||||
Cookie* aCookie, const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes) {
|
||||
MOZ_ASSERT(aCookie);
|
||||
|
||||
// The cookie is set with partitioned attribute. This is a CHIPS cookies.
|
||||
if (aCookie->RawIsPartitioned()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The originAttributes is not partitioned. This is not a partitioned cookie.
|
||||
if (aOriginAttributes.mPartitionKey.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoString scheme;
|
||||
nsAutoString baseDomain;
|
||||
int32_t port;
|
||||
bool foreignByAncestorContext;
|
||||
// Bail out early if the partition key is not valid.
|
||||
if (!OriginAttributes::ParsePartitionKey(aOriginAttributes.mPartitionKey,
|
||||
scheme, baseDomain, port,
|
||||
foreignByAncestorContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check whether the base domain of the cookie match the base domain in the
|
||||
// partitionKey and it is not an ABA context
|
||||
return aBaseDomain.Equals(NS_ConvertUTF16toUTF8(baseDomain)) &&
|
||||
!foreignByAncestorContext;
|
||||
}
|
||||
|
||||
bool CookieCommons::IsSafeTopLevelNav(nsIChannel* aChannel) {
|
||||
if (!aChannel) {
|
||||
return false;
|
||||
|
@ -126,10 +126,6 @@ class CookieCommons final {
|
||||
bool aInPrivateBrowsing,
|
||||
bool aUsingStorageAccess);
|
||||
|
||||
static bool IsFirstPartyPartitionedCookieWithoutCHIPS(
|
||||
Cookie* aCookie, const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes);
|
||||
|
||||
static bool IsSchemeSupported(nsIPrincipal* aPrincipal);
|
||||
static bool IsSchemeSupported(nsIURI* aURI);
|
||||
static bool IsSchemeSupported(const nsACString& aScheme);
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "CookiePersistentStorage.h"
|
||||
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
@ -206,102 +205,6 @@ SetInBrowserFromOriginAttributesSQLFunction::OnFunctionCall(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class FetchPartitionKeyFromOAsSQLFunction final : public mozIStorageFunction {
|
||||
~FetchPartitionKeyFromOAsSQLFunction() = default;
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_MOZISTORAGEFUNCTION
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(FetchPartitionKeyFromOAsSQLFunction, mozIStorageFunction);
|
||||
|
||||
NS_IMETHODIMP
|
||||
FetchPartitionKeyFromOAsSQLFunction::OnFunctionCall(
|
||||
mozIStorageValueArray* aFunctionArguments, nsIVariant** aResult) {
|
||||
nsresult rv;
|
||||
|
||||
nsAutoCString suffix;
|
||||
rv = aFunctionArguments->GetUTF8String(0, suffix);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
OriginAttributes attrsFromSuffix;
|
||||
bool success = attrsFromSuffix.PopulateFromSuffix(suffix);
|
||||
NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
|
||||
|
||||
RefPtr<nsVariant> outVar(new nsVariant());
|
||||
rv = outVar->SetAsAString(attrsFromSuffix.mPartitionKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
outVar.forget(aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class UpdateOAsWithPartitionHostSQLFunction final : public mozIStorageFunction {
|
||||
~UpdateOAsWithPartitionHostSQLFunction() = default;
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_MOZISTORAGEFUNCTION
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(UpdateOAsWithPartitionHostSQLFunction, mozIStorageFunction);
|
||||
|
||||
NS_IMETHODIMP
|
||||
UpdateOAsWithPartitionHostSQLFunction::OnFunctionCall(
|
||||
mozIStorageValueArray* aFunctionArguments, nsIVariant** aResult) {
|
||||
nsresult rv;
|
||||
|
||||
nsAutoCString formattedOriginAttributes;
|
||||
rv = aFunctionArguments->GetUTF8String(0, formattedOriginAttributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString partitionKeyHost;
|
||||
rv = aFunctionArguments->GetUTF8String(1, partitionKeyHost);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
OriginAttributes attrsFromSuffix;
|
||||
bool success = attrsFromSuffix.PopulateFromSuffix(formattedOriginAttributes);
|
||||
// On failure, do not alter the OA.
|
||||
if (!success) {
|
||||
RefPtr<nsVariant> outVar(new nsVariant());
|
||||
rv = outVar->SetAsACString(formattedOriginAttributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
outVar.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This is a bit hacky. However, CHIPS cookies can only be set in secure
|
||||
// contexts. So, the scheme has to be https.
|
||||
nsAutoCString schemeHost;
|
||||
schemeHost.AssignLiteral("https://");
|
||||
|
||||
if (*partitionKeyHost.get() == '.') {
|
||||
schemeHost.Append(nsDependentCSubstring(partitionKeyHost, 1));
|
||||
} else {
|
||||
schemeHost.Append(partitionKeyHost);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), schemeHost);
|
||||
// On failure, do not alter the OA.
|
||||
if (NS_FAILED(rv)) {
|
||||
RefPtr<nsVariant> outVar(new nsVariant());
|
||||
rv = outVar->SetAsACString(formattedOriginAttributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
outVar.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
attrsFromSuffix.SetPartitionKey(uri, false);
|
||||
attrsFromSuffix.CreateSuffix(formattedOriginAttributes);
|
||||
|
||||
RefPtr<nsVariant> outVar(new nsVariant());
|
||||
rv = outVar->SetAsACString(formattedOriginAttributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
outVar.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DBListenerErrorHandler impl:
|
||||
* Parent class for our async storage listeners that handles the logging of
|
||||
@ -1578,12 +1481,6 @@ CookiePersistentStorage::OpenDBResult CookiePersistentStorage::TryInitDB(
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
if (StaticPrefs::network_cookie_CHIPS_enabled() &&
|
||||
StaticPrefs::network_cookie_CHIPS_lastMigrateDatabase() <
|
||||
StaticPrefs::network_cookie_CHIPS_migrateDatabaseTarget()) {
|
||||
CookiePersistentStorage::MoveUnpartitionedChipsCookies();
|
||||
}
|
||||
|
||||
// check whether to import or just read in the db
|
||||
if (tableExists) {
|
||||
return Read();
|
||||
@ -1592,47 +1489,6 @@ CookiePersistentStorage::OpenDBResult CookiePersistentStorage::TryInitDB(
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
void CookiePersistentStorage::MoveUnpartitionedChipsCookies() {
|
||||
nsCOMPtr<mozIStorageFunction> fetchPartitionKeyFromOAs(
|
||||
new FetchPartitionKeyFromOAsSQLFunction());
|
||||
NS_ENSURE_TRUE_VOID(fetchPartitionKeyFromOAs);
|
||||
|
||||
constexpr auto fetchPartitionKeyFromOAsName =
|
||||
"FETCH_PARTITIONKEY_FROM_OAS"_ns;
|
||||
|
||||
nsresult rv = mSyncConn->CreateFunction(fetchPartitionKeyFromOAsName, 1,
|
||||
fetchPartitionKeyFromOAs);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
nsCOMPtr<mozIStorageFunction> updateOAsWithPartitionHost(
|
||||
new UpdateOAsWithPartitionHostSQLFunction());
|
||||
NS_ENSURE_TRUE_VOID(updateOAsWithPartitionHost);
|
||||
|
||||
constexpr auto updateOAsWithPartitionHostName =
|
||||
"UPDATE_OAS_WITH_PARTITION_HOST"_ns;
|
||||
|
||||
rv = mSyncConn->CreateFunction(updateOAsWithPartitionHostName, 2,
|
||||
updateOAsWithPartitionHost);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
// Move all cookies with the Partitioned attribute set into their first-party
|
||||
// partitioned storage by updating the origin attributes. Overwrite any
|
||||
// existing cookies that may already be there.
|
||||
rv = mSyncConn->ExecuteSimpleSQL(nsLiteralCString(
|
||||
"UPDATE OR REPLACE moz_cookies "
|
||||
"SET originAttributes = UPDATE_OAS_WITH_PARTITION_HOST(originAttributes, "
|
||||
"host) "
|
||||
"WHERE FETCH_PARTITIONKEY_FROM_OAS(originAttributes) = '' "
|
||||
"AND isPartitionedAttributeSet = 1;"));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
rv = mSyncConn->RemoveFunction(fetchPartitionKeyFromOAsName);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
rv = mSyncConn->RemoveFunction(updateOAsWithPartitionHostName);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
|
||||
void CookiePersistentStorage::RebuildCorruptDB() {
|
||||
NS_ASSERTION(!mDBConn, "shouldn't have an open db connection");
|
||||
NS_ASSERTION(mCorruptFlag == CookiePersistentStorage::CLOSING_FOR_REBUILD,
|
||||
@ -1970,23 +1826,6 @@ void CookiePersistentStorage::InitDBConn() {
|
||||
// evicted.
|
||||
RefPtr<Cookie> cookie =
|
||||
Cookie::CreateValidated(*tuple.cookie, tuple.originAttributes);
|
||||
|
||||
// Clean up the invalid first-party partitioned cookies that don't have
|
||||
// the 'partitioned' cookie attribution. This will also ensure that we don't
|
||||
// read the cookie into memory.
|
||||
if (CookieCommons::IsFirstPartyPartitionedCookieWithoutCHIPS(
|
||||
cookie, tuple.key.mBaseDomain, tuple.key.mOriginAttributes)) {
|
||||
// We cannot directly use the cookie after validation because the
|
||||
// timestamps could be different from the cookies in DB. So, we need to
|
||||
// create one from the cookie struct.
|
||||
RefPtr<Cookie> invalidCookie =
|
||||
Cookie::Create(*tuple.cookie, tuple.originAttributes);
|
||||
cleanupCookies.AppendElement(invalidCookie);
|
||||
mozilla::glean::networking::
|
||||
cookie_count_invalid_first_party_partitioned_in_db.Add(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
AddCookieToList(tuple.key.mBaseDomain, tuple.key.mOriginAttributes, cookie);
|
||||
}
|
||||
|
||||
@ -2015,15 +1854,6 @@ void CookiePersistentStorage::InitDBConn() {
|
||||
RemoveCookieFromDB(*cookie);
|
||||
}
|
||||
|
||||
// We will have migrated CHIPS cookies if the pref is set, and .unset it
|
||||
// to prevent dupliacted work. This has to happen in the main thread though,
|
||||
// so we waited to this point.
|
||||
if (StaticPrefs::network_cookie_CHIPS_enabled()) {
|
||||
Preferences::SetUint(
|
||||
"network.cookie.CHIPS.lastMigrateDatabase",
|
||||
StaticPrefs::network_cookie_CHIPS_migrateDatabaseTarget());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
os->NotifyObservers(nullptr, "cookie-db-read", nullptr);
|
||||
|
@ -97,7 +97,6 @@ class CookiePersistentStorage final : public CookieStorage {
|
||||
|
||||
OpenDBResult TryInitDB(bool aRecreateDB);
|
||||
OpenDBResult Read();
|
||||
void MoveUnpartitionedChipsCookies();
|
||||
|
||||
nsresult CreateTableWorker(const char* aName);
|
||||
nsresult CreateTable();
|
||||
|
@ -696,7 +696,7 @@ CookieService::Add(const nsACString& aHost, const nsACString& aPath,
|
||||
bool aIsSecure, bool aIsHttpOnly, bool aIsSession,
|
||||
int64_t aExpiry, JS::Handle<JS::Value> aOriginAttributes,
|
||||
int32_t aSameSite, nsICookie::schemeType aSchemeMap,
|
||||
bool aIsPartitioned, JSContext* aCx) {
|
||||
JSContext* aCx) {
|
||||
OriginAttributes attrs;
|
||||
|
||||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
@ -704,8 +704,8 @@ CookieService::Add(const nsACString& aHost, const nsACString& aPath,
|
||||
}
|
||||
|
||||
return AddNative(aHost, aPath, aName, aValue, aIsSecure, aIsHttpOnly,
|
||||
aIsSession, aExpiry, &attrs, aSameSite, aSchemeMap,
|
||||
aIsPartitioned, nullptr);
|
||||
aIsSession, aExpiry, &attrs, aSameSite, aSchemeMap, false,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsresult)
|
||||
|
@ -308,17 +308,6 @@ CookieServiceChild::RecordDocumentCookie(Cookie* aCookie,
|
||||
CookieCommons::GetBaseDomainFromHost(mTLDService, aCookie->Host(),
|
||||
baseDomain);
|
||||
|
||||
if (CookieCommons::IsFirstPartyPartitionedCookieWithoutCHIPS(
|
||||
aCookie, baseDomain, aAttrs)) {
|
||||
COOKIE_LOGSTRING(LogLevel::Error,
|
||||
("Invalid first-party partitioned cookie without "
|
||||
"partitioned cookie attribution from the document."));
|
||||
mozilla::glean::networking::set_invalid_first_party_partitioned_cookie.Add(
|
||||
1);
|
||||
MOZ_DIAGNOSTIC_ASSERT(false);
|
||||
return CookieNotificationAction::NoActionNeeded;
|
||||
}
|
||||
|
||||
CookieKey key(baseDomain, aAttrs);
|
||||
CookiesList* cookiesList = nullptr;
|
||||
mCookiesMap.Get(key, &cookiesList);
|
||||
|
@ -602,17 +602,6 @@ void CookieStorage::AddCookie(CookieParser* aCookieParser,
|
||||
bool aFromHttp, bool aIsThirdParty,
|
||||
dom::BrowsingContext* aBrowsingContext,
|
||||
const nsID* aOperationID) {
|
||||
if (CookieCommons::IsFirstPartyPartitionedCookieWithoutCHIPS(
|
||||
aCookie, aBaseDomain, aOriginAttributes)) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
|
||||
"Invalid first-party partitioned cookie without "
|
||||
"partitioned cookie attribution.");
|
||||
mozilla::glean::networking::set_invalid_first_party_partitioned_cookie.Add(
|
||||
1);
|
||||
MOZ_DIAGNOSTIC_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t currentTime = aCurrentTimeInUsec / PR_USEC_PER_SEC;
|
||||
|
||||
CookieListIter exactIter{};
|
||||
|
@ -118,10 +118,6 @@ interface nsICookieManager : nsISupports
|
||||
* the originAttributes of this cookie.
|
||||
* @param aSameSite
|
||||
* the SameSite attribute.
|
||||
* @param aSchemeMap
|
||||
* the schemes this cookie has been set on. See nsICookie.idl.
|
||||
* @param aIsPartitioned
|
||||
* true if the cookie should be stored with the Partitioned attribute.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
void add(in AUTF8String aHost,
|
||||
@ -134,8 +130,7 @@ interface nsICookieManager : nsISupports
|
||||
in int64_t aExpiry,
|
||||
in jsval aOriginAttributes,
|
||||
in int32_t aSameSite,
|
||||
in nsICookie_schemeType aSchemeMap,
|
||||
[optional] in boolean aIsPartitioned);
|
||||
in nsICookie_schemeType aSchemeMap);
|
||||
|
||||
[notxpcom]
|
||||
nsresult addNative(in AUTF8String aHost,
|
||||
|
@ -215,36 +215,6 @@ networking:
|
||||
- edgul@mozilla.com
|
||||
expires: 146
|
||||
|
||||
cookie_count_invalid_first_party_partitioned_in_db:
|
||||
type: counter
|
||||
description: >
|
||||
This counts the number of invalid first-party partitioned cookies that
|
||||
don't have the partitioned cookie attribution(CHIPS).
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/1922193
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/1922193
|
||||
notification_emails:
|
||||
- bvandersloot@mozilla.com
|
||||
- tihuang@mozilla.com
|
||||
- edgul@mozilla.com
|
||||
expires: 146
|
||||
|
||||
set_invalid_first_party_partitioned_cookie:
|
||||
type: counter
|
||||
description: >
|
||||
This counts the number of times we set an invalid first-party partitioned
|
||||
cookie.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/1922193
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/1922193
|
||||
notification_emails:
|
||||
- bvandersloot@mozilla.com
|
||||
- tihuang@mozilla.com
|
||||
- edgul@mozilla.com
|
||||
expires: 146
|
||||
|
||||
cookie_purge_max:
|
||||
type: custom_distribution
|
||||
description: >
|
||||
|
@ -1,236 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(async function test_chips_migration() {
|
||||
// Set up a profile.
|
||||
let profile = do_get_profile();
|
||||
|
||||
// Start the cookieservice, to force creation of a database.
|
||||
Services.cookies.sessionCookies;
|
||||
|
||||
// Close the profile.
|
||||
await promise_close_profile();
|
||||
|
||||
// Remove the cookie file in order to create another database file.
|
||||
do_get_cookie_file(profile).remove(false);
|
||||
|
||||
// Create a schema 14 database.
|
||||
let database = new CookieDatabaseConnection(do_get_cookie_file(profile), 14);
|
||||
|
||||
let now = Date.now() * 1000;
|
||||
let expiry = Math.round(now / 1e6 + 1000);
|
||||
|
||||
// Populate db with a first-party unpartitioned cookies
|
||||
let cookie = new Cookie(
|
||||
"test",
|
||||
"Some data",
|
||||
"example.com",
|
||||
"/",
|
||||
expiry,
|
||||
now,
|
||||
now,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
{},
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
false // isPartitioned
|
||||
);
|
||||
database.insertCookie(cookie);
|
||||
|
||||
// Populate db with a first-party unpartitioned cookies with the partitioned attribute
|
||||
cookie = new Cookie(
|
||||
"test partitioned",
|
||||
"Some data",
|
||||
"example.com",
|
||||
"/",
|
||||
expiry,
|
||||
now,
|
||||
now,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
{},
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
true // isPartitioned
|
||||
);
|
||||
database.insertCookie(cookie);
|
||||
|
||||
// Populate db with a first-party unpartitioned cookies with the partitioned attribute
|
||||
cookie = new Cookie(
|
||||
"test overwrite",
|
||||
"Overwritten",
|
||||
"example.com",
|
||||
"/",
|
||||
expiry,
|
||||
now,
|
||||
now,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
{},
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
true // isPartitioned
|
||||
);
|
||||
database.insertCookie(cookie);
|
||||
|
||||
// Populate db with a first-party unpartitioned cookies with the partitioned attribute
|
||||
cookie = new Cookie(
|
||||
"test overwrite",
|
||||
"Did not overwrite",
|
||||
"example.com",
|
||||
"/",
|
||||
expiry,
|
||||
now,
|
||||
now,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
{ partitionKey: "(https,example.com)" },
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
true // isPartitioned
|
||||
);
|
||||
database.insertCookie(cookie);
|
||||
|
||||
database.close();
|
||||
database = null;
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("network.cookie.CHIPS.enabled");
|
||||
Services.prefs.clearUserPref("network.cookie.CHIPS.migrateDatabase");
|
||||
});
|
||||
|
||||
// Reload profile.
|
||||
Services.prefs.setBoolPref("network.cookie.CHIPS.enabled", true);
|
||||
Services.prefs.setIntPref("network.cookie.CHIPS.lastMigrateDatabase", 0);
|
||||
Services.prefs.setIntPref("network.cookie.CHIPS.migrateDatabaseTarget", 0);
|
||||
await promise_load_profile();
|
||||
|
||||
// Make sure there were no changes
|
||||
Assert.equal(
|
||||
Services.cookies.getCookiesFromHost("example.com", {}).length,
|
||||
3
|
||||
);
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {})
|
||||
.filter(cookie => cookie.name == "test").length,
|
||||
1
|
||||
);
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {})
|
||||
.filter(cookie => cookie.name == "test partitioned").length,
|
||||
1
|
||||
);
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {})
|
||||
.filter(cookie => cookie.name == "test overwrite").length,
|
||||
1
|
||||
);
|
||||
Assert.equal(
|
||||
Services.cookies.getCookiesFromHost("example.com", {
|
||||
partitionKey: "(https,example.com)",
|
||||
}).length,
|
||||
1
|
||||
);
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {})
|
||||
.filter(cookie => cookie.name == "test overwrite").length,
|
||||
1
|
||||
);
|
||||
|
||||
// Close the profile.
|
||||
await promise_close_profile();
|
||||
|
||||
// Reload profile.
|
||||
await Services.prefs.setBoolPref("network.cookie.CHIPS.enabled", true);
|
||||
await Services.prefs.setIntPref(
|
||||
"network.cookie.CHIPS.migrateDatabaseTarget",
|
||||
1000
|
||||
);
|
||||
await promise_load_profile();
|
||||
|
||||
// Check if the first-party unpartitioned cookie is still there
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {})
|
||||
.filter(cookie => cookie.name == "test").length,
|
||||
1
|
||||
);
|
||||
|
||||
// Check that we no longer have Partitioned cookies in the unpartitioned storage
|
||||
Assert.equal(
|
||||
Services.cookies.getCookiesFromHost("example.com", {}).length,
|
||||
1
|
||||
);
|
||||
|
||||
// Check that we only have our two partitioned cookies
|
||||
Assert.equal(
|
||||
Services.cookies.getCookiesFromHost("example.com", {
|
||||
partitionKey: "(https,example.com)",
|
||||
}).length,
|
||||
2
|
||||
);
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {
|
||||
partitionKey: "(https,example.com)",
|
||||
})
|
||||
.filter(cookie => cookie.name == "test").length,
|
||||
0
|
||||
);
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {
|
||||
partitionKey: "(https,example.com)",
|
||||
})
|
||||
.filter(cookie => cookie.name == "test partitioned").length,
|
||||
1
|
||||
);
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {
|
||||
partitionKey: "(https,example.com)",
|
||||
})
|
||||
.filter(cookie => cookie.name == "test overwrite").length,
|
||||
1
|
||||
);
|
||||
|
||||
// Test that we overwrote the value of the cookie in the partition with the
|
||||
// value that was not partitioned
|
||||
Assert.equal(
|
||||
Services.cookies
|
||||
.getCookiesFromHost("example.com", {
|
||||
partitionKey: "(https,example.com)",
|
||||
})
|
||||
.filter(cookie => cookie.name == "test overwrite")[0].value,
|
||||
"Overwritten"
|
||||
);
|
||||
|
||||
// Make sure we cleared the migration pref as part of the migration
|
||||
Assert.equal(
|
||||
Services.prefs.getIntPref("network.cookie.CHIPS.lastMigrateDatabase"),
|
||||
1000
|
||||
);
|
||||
|
||||
// Cleanup
|
||||
Services.cookies.removeAll();
|
||||
do_close_profile();
|
||||
});
|
@ -1,201 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// The test ensure we remove first-party partitioned cookies that don't have
|
||||
// partitioned attribute.
|
||||
|
||||
add_task(async function run_test() {
|
||||
// Set up a profile.
|
||||
let profile = do_get_profile();
|
||||
|
||||
// Start the cookieservice, to force creation of a database.
|
||||
Services.cookies.sessionCookies;
|
||||
|
||||
// Close the profile.
|
||||
await promise_close_profile();
|
||||
|
||||
// Create a schema 14 database.
|
||||
let schema14db = new CookieDatabaseConnection(
|
||||
do_get_cookie_file(profile),
|
||||
14
|
||||
);
|
||||
|
||||
let now = Math.round(Date.now() / 1000);
|
||||
|
||||
// Create an invalid first-party partitioned cookie.
|
||||
let invalidFPCookie = new Cookie(
|
||||
"invalid",
|
||||
"bad",
|
||||
"example.com",
|
||||
"/",
|
||||
now + 34560000,
|
||||
now,
|
||||
now,
|
||||
false, // isSession
|
||||
true, // isSecure
|
||||
false, // isHttpOnly
|
||||
false, // isBrowserElement
|
||||
{ partitionKey: "(https,example.com)" },
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
false // isPartitioned
|
||||
);
|
||||
schema14db.insertCookie(invalidFPCookie);
|
||||
|
||||
// Create a valid first-party partitioned cookie(CHIPS).
|
||||
let valid1stCHIPS = new Cookie(
|
||||
"valid1stCHIPS",
|
||||
"good",
|
||||
"example.com",
|
||||
"/",
|
||||
now + 34560000,
|
||||
now,
|
||||
now,
|
||||
false, // isSession
|
||||
true, // isSecure
|
||||
false, // isHttpOnly
|
||||
false, // isBrowserElement
|
||||
{ partitionKey: "(https,example.com)" },
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
true // isPartitioned
|
||||
);
|
||||
schema14db.insertCookie(valid1stCHIPS);
|
||||
|
||||
// Create a valid unpartitioned cookie.
|
||||
let unpartitionedCookie = new Cookie(
|
||||
"valid",
|
||||
"good",
|
||||
"example.com",
|
||||
"/",
|
||||
now + 34560000,
|
||||
now,
|
||||
now,
|
||||
false, // isSession
|
||||
true, // isSecure
|
||||
false, // isHttpOnly
|
||||
false, // isBrowserElement
|
||||
{},
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
false // isPartitioned
|
||||
);
|
||||
schema14db.insertCookie(unpartitionedCookie);
|
||||
|
||||
// Create valid third-party partitioned TCP cookie.
|
||||
let valid3rdTCPCookie = new Cookie(
|
||||
"valid3rdTCP",
|
||||
"good",
|
||||
"example.com",
|
||||
"/",
|
||||
now + 34560000,
|
||||
now,
|
||||
now,
|
||||
false, // isSession
|
||||
true, // isSecure
|
||||
false, // isHttpOnly
|
||||
false, // isBrowserElement
|
||||
{ partitionKey: "(https,example.org)" },
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
false // isPartitioned
|
||||
);
|
||||
schema14db.insertCookie(valid3rdTCPCookie);
|
||||
|
||||
// Create valid third-party partitioned CHIPS cookie.
|
||||
let valid3rdCHIPSCookie = new Cookie(
|
||||
"valid3rdCHIPS",
|
||||
"good",
|
||||
"example.com",
|
||||
"/",
|
||||
now + 34560000,
|
||||
now,
|
||||
now,
|
||||
false, // isSession
|
||||
true, // isSecure
|
||||
false, // isHttpOnly
|
||||
false, // isBrowserElement
|
||||
{ partitionKey: "(https,example.org)" },
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SAMESITE_NONE,
|
||||
Ci.nsICookie.SCHEME_UNSET,
|
||||
true // isPartitioned
|
||||
);
|
||||
schema14db.insertCookie(valid3rdCHIPSCookie);
|
||||
|
||||
schema14db.close();
|
||||
schema14db = null;
|
||||
|
||||
// Check if we have the right testing entries
|
||||
{
|
||||
const dbConnection = Services.storage.openDatabase(
|
||||
do_get_cookie_file(profile)
|
||||
);
|
||||
const stmt = dbConnection.createStatement(
|
||||
"SELECT count(name) FROM moz_cookies WHERE host = 'example.com';"
|
||||
);
|
||||
const success = stmt.executeStep();
|
||||
Assert.ok(success);
|
||||
|
||||
const count = stmt.getInt32(0);
|
||||
Assert.equal(count, 5);
|
||||
stmt.finalize();
|
||||
dbConnection.close();
|
||||
}
|
||||
|
||||
// Reload profile.
|
||||
await promise_load_profile();
|
||||
|
||||
// Check the number of unpartitioned cookies is correct, and we only have
|
||||
// good cookies.
|
||||
let cookies = Services.cookies.getCookiesFromHost("example.com", {});
|
||||
Assert.equal(cookies.length, 1);
|
||||
for (const cookie of cookies) {
|
||||
Assert.equal(cookie.value, "good");
|
||||
}
|
||||
|
||||
// Check the number of first-party partitioned cookies is correct, and we only
|
||||
// have good cookies.
|
||||
cookies = Services.cookies.getCookiesFromHost("example.com", {
|
||||
partitionKey: "(https,example.com)",
|
||||
});
|
||||
Assert.equal(cookies.length, 1);
|
||||
for (const cookie of cookies) {
|
||||
Assert.equal(cookie.value, "good");
|
||||
}
|
||||
|
||||
// Check the number of third-party partitioned cookies is correct, and we only
|
||||
// have good cookies.
|
||||
cookies = Services.cookies.getCookiesFromHost("example.com", {
|
||||
partitionKey: "(https,example.org)",
|
||||
});
|
||||
Assert.equal(cookies.length, 2);
|
||||
for (const cookie of cookies) {
|
||||
Assert.equal(cookie.value, "good");
|
||||
}
|
||||
|
||||
// Ensure the invalid cookies is gone in the DB.
|
||||
{
|
||||
const dbConnection = Services.storage.openDatabase(
|
||||
do_get_cookie_file(profile)
|
||||
);
|
||||
const stmt = dbConnection.createStatement(
|
||||
"SELECT count(name) FROM moz_cookies WHERE value = 'bad';"
|
||||
);
|
||||
const success = stmt.executeStep();
|
||||
Assert.ok(success);
|
||||
|
||||
const count = stmt.getInt32(0);
|
||||
Assert.equal(count, 0);
|
||||
stmt.finalize();
|
||||
dbConnection.close();
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
Services.cookies.removeAll();
|
||||
do_close_profile();
|
||||
});
|
@ -505,8 +505,6 @@ skip-if = ["os == 'linux' && bits == 64 && !debug"] #Bug 1553353
|
||||
|
||||
["test_cookies_partition_counting.js"]
|
||||
|
||||
["test_cookies_partition_migration.js"]
|
||||
|
||||
["test_cookies_privatebrowsing.js"]
|
||||
|
||||
["test_cookies_profile_close.js"]
|
||||
@ -1071,8 +1069,6 @@ skip-if = [
|
||||
|
||||
["test_referrer_policy.js"]
|
||||
|
||||
["test_remove_invalid_first_party_partitioned_cookie.js"]
|
||||
|
||||
["test_reopen.js"]
|
||||
|
||||
["test_reply_without_content_type.js"]
|
||||
|
@ -298,8 +298,6 @@ class StorageModule extends RootBiDiModule {
|
||||
schemeType = Ci.nsICookie.SCHEME_HTTP;
|
||||
}
|
||||
|
||||
const isPartitioned = originAttributes.partitionKey?.length > 0;
|
||||
|
||||
try {
|
||||
Services.cookies.add(
|
||||
domain,
|
||||
@ -313,8 +311,7 @@ class StorageModule extends RootBiDiModule {
|
||||
expiry === null ? MAX_COOKIE_EXPIRY : expiry,
|
||||
originAttributes,
|
||||
this.#getSameSitePlatformProperty(sameSite),
|
||||
schemeType,
|
||||
isPartitioned
|
||||
schemeType
|
||||
);
|
||||
} catch (e) {
|
||||
throw new lazy.error.UnableToSetCookieError(e);
|
||||
|
@ -10,3 +10,8 @@
|
||||
[test_partition_user_context]
|
||||
disabled:
|
||||
if os == "android": bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1877953
|
||||
|
||||
[test_partition_context_iframe[cross_origin\]]
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1865198
|
||||
expected:
|
||||
if not nightly_build: FAIL
|
||||
|
@ -0,0 +1,10 @@
|
||||
[partition.py]
|
||||
[test_partition_context]
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1865198
|
||||
expected:
|
||||
if not nightly_build: FAIL
|
||||
|
||||
[test_partition_context_iframe[cross_origin\]]
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1865198
|
||||
expected:
|
||||
if not nightly_build: FAIL
|
@ -702,8 +702,6 @@ this.cookies = class extends ExtensionAPIPersistent {
|
||||
schemeType = Ci.nsICookie.SCHEME_FILE;
|
||||
}
|
||||
|
||||
let isPartitioned = originAttributes.partitionKey?.length > 0;
|
||||
|
||||
// The permission check may have modified the domain, so use
|
||||
// the new value instead.
|
||||
Services.cookies.add(
|
||||
@ -717,8 +715,7 @@ this.cookies = class extends ExtensionAPIPersistent {
|
||||
expiry,
|
||||
originAttributes,
|
||||
sameSite,
|
||||
schemeType,
|
||||
isPartitioned
|
||||
schemeType
|
||||
);
|
||||
|
||||
return self.cookies.get(details);
|
||||
|
@ -2208,12 +2208,6 @@ networking:
|
||||
setPref:
|
||||
branch: default
|
||||
pref: "network.cookie.CHIPS.enabled"
|
||||
chipsMigrationTarget:
|
||||
description: What CHIPS migration count target the browser should reach.
|
||||
type: int
|
||||
setPref:
|
||||
branch: default
|
||||
pref: "network.cookie.CHIPS.migrateDatabaseTarget"
|
||||
chipsPartitionLimitEnabled:
|
||||
description: Whether we enforce CHIPS partition limit
|
||||
type: boolean
|
||||
|
Loading…
Reference in New Issue
Block a user