forked from mirrors/gecko-dev
Bug 1874174 - Send cookies from partitioned and unpartitioned jar. (2/2) r=bvandersloot,cookie-reviewers,edgul
Differential Revision: https://phabricator.services.mozilla.com/D204906
This commit is contained in:
parent
89f7ff27cc
commit
8600838345
8 changed files with 695 additions and 303 deletions
|
|
@ -494,9 +494,11 @@ bool CookieCommons::ShouldIncludeCrossSiteCookieForDocument(
|
|||
int32_t sameSiteAttr = 0;
|
||||
aCookie->GetSameSite(&sameSiteAttr);
|
||||
|
||||
// CHIPS - If a third-party has storage access it can access both it's
|
||||
// partitioned and unpartitioned cookie jars, else its cookies are blocked.
|
||||
if (aDocument->CookieJarSettings()->GetPartitionForeign() &&
|
||||
StaticPrefs::network_cookie_cookieBehavior_optInPartitioning() &&
|
||||
!aCookie->IsPartitioned()) {
|
||||
!aCookie->IsPartitioned() && !aDocument->UsingStorageAccess()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -373,15 +373,6 @@ CookieService::GetCookieStringFromDocument(Document* aDocument,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> cookiePrincipal =
|
||||
aDocument->EffectiveCookiePrincipal();
|
||||
|
||||
// TODO (Bug 1874174): A document could access both unpartitioned and
|
||||
// partitioned cookie jars. We will need to prepare partitioned and
|
||||
// unpartitioned principals for access both cookie jars.
|
||||
nsTArray<nsCOMPtr<nsIPrincipal>> principals;
|
||||
principals.AppendElement(cookiePrincipal);
|
||||
|
||||
bool thirdParty = true;
|
||||
nsPIDOMWindowInner* innerWindow = aDocument->GetInnerWindow();
|
||||
// in gtests we don't have a window, let's consider those requests as 3rd
|
||||
|
|
@ -395,6 +386,26 @@ CookieService::GetCookieStringFromDocument(Document* aDocument,
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> cookiePrincipal =
|
||||
aDocument->EffectiveCookiePrincipal();
|
||||
|
||||
nsTArray<nsCOMPtr<nsIPrincipal>> principals;
|
||||
principals.AppendElement(cookiePrincipal);
|
||||
|
||||
// CHIPS - If CHIPS is enabled the partitioned cookie jar is always available
|
||||
// (and therefore the partitioned principal), the unpartitioned cookie jar is
|
||||
// only available in first-party or third-party with storageAccess contexts.
|
||||
bool isCHIPS = StaticPrefs::network_cookie_cookieBehavior_optInPartitioning();
|
||||
bool isUnpartitioned =
|
||||
cookiePrincipal->OriginAttributesRef().mPartitionKey.IsEmpty();
|
||||
if (isCHIPS && isUnpartitioned) {
|
||||
// Assert that we are only doing this if we are first-party or third-party
|
||||
// with storageAccess.
|
||||
MOZ_ASSERT(!thirdParty || aDocument->UsingStorageAccess());
|
||||
// Add the partitioned principal to principals
|
||||
principals.AppendElement(aDocument->PartitionedPrincipal());
|
||||
}
|
||||
|
||||
nsTArray<Cookie*> cookieList;
|
||||
|
||||
for (auto& principal : principals) {
|
||||
|
|
@ -519,20 +530,40 @@ CookieService::GetCookieStringFromHttp(nsIURI* aHostURI, nsIChannel* aChannel,
|
|||
ThirdPartyAnalysisResult result = mThirdPartyUtil->AnalyzeChannel(
|
||||
aChannel, false, aHostURI, nullptr, &rejectedReason);
|
||||
|
||||
OriginAttributes attrs;
|
||||
StoragePrincipalHelper::GetOriginAttributes(
|
||||
aChannel, attrs, StoragePrincipalHelper::eStorageAccessPrincipal);
|
||||
|
||||
bool isSafeTopLevelNav = CookieCommons::IsSafeTopLevelNav(aChannel);
|
||||
bool hadCrossSiteRedirects = false;
|
||||
bool isSameSiteForeign = CookieCommons::IsSameSiteForeign(
|
||||
aChannel, aHostURI, &hadCrossSiteRedirects);
|
||||
|
||||
// TODO (Bug 1874174): A channel could load both unpartitioned and partitioned
|
||||
// cookie jars together. We will need to get cookies from both unpartitioned
|
||||
// and partitioned cookie jars according to storage access.
|
||||
OriginAttributes storageOriginAttributes;
|
||||
StoragePrincipalHelper::GetOriginAttributes(
|
||||
aChannel, storageOriginAttributes,
|
||||
StoragePrincipalHelper::eStorageAccessPrincipal);
|
||||
|
||||
nsTArray<OriginAttributes> originAttributesList;
|
||||
originAttributesList.AppendElement(attrs);
|
||||
originAttributesList.AppendElement(storageOriginAttributes);
|
||||
|
||||
// CHIPS - If CHIPS is enabled the partitioned cookie jar is always available
|
||||
// (and therefore the partitioned OriginAttributes), the unpartitioned cookie
|
||||
// jar is only available in first-party or third-party with storageAccess
|
||||
// contexts.
|
||||
bool isCHIPS = StaticPrefs::network_cookie_cookieBehavior_optInPartitioning();
|
||||
bool isUnpartitioned = storageOriginAttributes.mPartitionKey.IsEmpty();
|
||||
if (isCHIPS && isUnpartitioned) {
|
||||
// Assert that we are only doing this if we are first-party or third-party
|
||||
// with storageAccess.
|
||||
MOZ_ASSERT(
|
||||
!result.contains(ThirdPartyAnalysis::IsForeign) ||
|
||||
result.contains(ThirdPartyAnalysis::IsStorageAccessPermissionGranted));
|
||||
// Add the partitioned principal to principals
|
||||
OriginAttributes partitionedOriginAttributes;
|
||||
StoragePrincipalHelper::GetOriginAttributes(
|
||||
aChannel, partitionedOriginAttributes,
|
||||
StoragePrincipalHelper::ePartitionedPrincipal);
|
||||
originAttributesList.AppendElement(partitionedOriginAttributes);
|
||||
// Assert partitionedOAs have partitioneKey set.
|
||||
MOZ_ASSERT(!partitionedOriginAttributes.mPartitionKey.IsEmpty());
|
||||
}
|
||||
|
||||
AutoTArray<Cookie*, 8> foundCookieList;
|
||||
GetCookiesForURI(
|
||||
|
|
|
|||
|
|
@ -96,9 +96,9 @@ RefPtr<GenericPromise> CookieServiceChild::TrackCookieLoad(
|
|||
aChannel->GetURI(getter_AddRefs(uri));
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
|
||||
OriginAttributes attrs = loadInfo->GetOriginAttributes();
|
||||
OriginAttributes storageOriginAttributes = loadInfo->GetOriginAttributes();
|
||||
StoragePrincipalHelper::PrepareEffectiveStoragePrincipalOriginAttributes(
|
||||
aChannel, attrs);
|
||||
aChannel, storageOriginAttributes);
|
||||
|
||||
bool isSafeTopLevelNav = CookieCommons::IsSafeTopLevelNav(aChannel);
|
||||
bool hadCrossSiteRedirects = false;
|
||||
|
|
@ -107,11 +107,30 @@ RefPtr<GenericPromise> CookieServiceChild::TrackCookieLoad(
|
|||
|
||||
RefPtr<CookieServiceChild> self(this);
|
||||
|
||||
// TODO (Bug 1874174): A channel could access both unpartitioned and
|
||||
// partitioned cookie jars. We will need to pass partitioned and unpartitioned
|
||||
// originAttributes according the storage access.
|
||||
nsTArray<OriginAttributes> attrsList;
|
||||
attrsList.AppendElement(attrs);
|
||||
nsTArray<OriginAttributes> originAttributesList;
|
||||
originAttributesList.AppendElement(storageOriginAttributes);
|
||||
|
||||
// CHIPS - If CHIPS is enabled the partitioned cookie jar is always available
|
||||
// (and therefore the partitioned OriginAttributes), the unpartitioned cookie
|
||||
// jar is only available in first-party or third-party with storageAccess
|
||||
// contexts.
|
||||
bool isCHIPS = StaticPrefs::network_cookie_cookieBehavior_optInPartitioning();
|
||||
bool isUnpartitioned = storageOriginAttributes.mPartitionKey.IsEmpty();
|
||||
if (isCHIPS && isUnpartitioned) {
|
||||
// Assert that we are only doing this if we are first-party or third-party
|
||||
// with storageAccess.
|
||||
MOZ_ASSERT(
|
||||
!result.contains(ThirdPartyAnalysis::IsForeign) ||
|
||||
result.contains(ThirdPartyAnalysis::IsStorageAccessPermissionGranted));
|
||||
// Add the partitioned principal to principals.
|
||||
OriginAttributes partitionedOriginAttributes;
|
||||
StoragePrincipalHelper::GetOriginAttributes(
|
||||
aChannel, partitionedOriginAttributes,
|
||||
StoragePrincipalHelper::ePartitionedPrincipal);
|
||||
originAttributesList.AppendElement(partitionedOriginAttributes);
|
||||
// Assert partitionedOAs have partitioneKey set.
|
||||
MOZ_ASSERT(!partitionedOriginAttributes.mPartitionKey.IsEmpty());
|
||||
}
|
||||
|
||||
return SendGetCookieList(
|
||||
uri, result.contains(ThirdPartyAnalysis::IsForeign),
|
||||
|
|
@ -121,7 +140,7 @@ RefPtr<GenericPromise> CookieServiceChild::TrackCookieLoad(
|
|||
result.contains(
|
||||
ThirdPartyAnalysis::IsStorageAccessPermissionGranted),
|
||||
rejectedReason, isSafeTopLevelNav, isSameSiteForeign,
|
||||
hadCrossSiteRedirects, attrsList)
|
||||
hadCrossSiteRedirects, originAttributesList)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[self, uri](const nsTArray<CookieStructTable>& aCookiesListTable) {
|
||||
|
|
@ -325,15 +344,6 @@ CookieServiceChild::GetCookieStringFromDocument(dom::Document* aDocument,
|
|||
|
||||
aCookieString.Truncate();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> cookiePrincipal =
|
||||
aDocument->EffectiveCookiePrincipal();
|
||||
|
||||
// TODO (Bug 1874174): A document could access both unpartitioned and
|
||||
// partitioned cookie jars. We will need to prepare partitioned and
|
||||
// unpartitioned principals for access both cookie jars.
|
||||
nsTArray<nsCOMPtr<nsIPrincipal>> principals;
|
||||
principals.AppendElement(cookiePrincipal);
|
||||
|
||||
bool thirdParty = true;
|
||||
nsPIDOMWindowInner* innerWindow = aDocument->GetInnerWindow();
|
||||
// in gtests we don't have a window, let's consider those requests as 3rd
|
||||
|
|
@ -347,6 +357,26 @@ CookieServiceChild::GetCookieStringFromDocument(dom::Document* aDocument,
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> cookiePrincipal =
|
||||
aDocument->EffectiveCookiePrincipal();
|
||||
|
||||
nsTArray<nsCOMPtr<nsIPrincipal>> principals;
|
||||
principals.AppendElement(cookiePrincipal);
|
||||
|
||||
// CHIPS - If CHIPS is enabled the partitioned cookie jar is always available
|
||||
// (and therefore the partitioned principal), the unpartitioned cookie jar is
|
||||
// only available in first-party or third-party with storageAccess contexts.
|
||||
bool isCHIPS = StaticPrefs::network_cookie_cookieBehavior_optInPartitioning();
|
||||
bool isUnpartitioned =
|
||||
cookiePrincipal->OriginAttributesRef().mPartitionKey.IsEmpty();
|
||||
if (isCHIPS && isUnpartitioned) {
|
||||
// Assert that we are only doing this if we are first-party or third-party
|
||||
// with storageAccess.
|
||||
MOZ_ASSERT(!thirdParty || aDocument->UsingStorageAccess());
|
||||
// Add the partitioned principal to principals
|
||||
principals.AppendElement(aDocument->PartitionedPrincipal());
|
||||
}
|
||||
|
||||
for (auto& principal : principals) {
|
||||
if (!CookieCommons::IsSchemeSupported(principal)) {
|
||||
return NS_OK;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsMixedContentBlocker.h"
|
||||
|
|
@ -119,17 +120,11 @@ void CookieServiceParent::TrackCookieLoad(nsIChannel* aChannel) {
|
|||
aChannel->GetURI(getter_AddRefs(uri));
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
OriginAttributes attrs = loadInfo->GetOriginAttributes();
|
||||
bool isSafeTopLevelNav = CookieCommons::IsSafeTopLevelNav(aChannel);
|
||||
bool hadCrossSiteRedirects = false;
|
||||
bool isSameSiteForeign =
|
||||
CookieCommons::IsSameSiteForeign(aChannel, uri, &hadCrossSiteRedirects);
|
||||
|
||||
// TODO (Bug 1874174): A channel could load both unpartitioned and partitioned
|
||||
// cookie jars together. We will need to track both originAttributes for them.
|
||||
StoragePrincipalHelper::PrepareEffectiveStoragePrincipalOriginAttributes(
|
||||
aChannel, attrs);
|
||||
|
||||
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil;
|
||||
thirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID);
|
||||
|
||||
|
|
@ -137,8 +132,34 @@ void CookieServiceParent::TrackCookieLoad(nsIChannel* aChannel) {
|
|||
ThirdPartyAnalysisResult result = thirdPartyUtil->AnalyzeChannel(
|
||||
aChannel, false, nullptr, nullptr, &rejectedReason);
|
||||
|
||||
OriginAttributes storageOriginAttributes = loadInfo->GetOriginAttributes();
|
||||
StoragePrincipalHelper::PrepareEffectiveStoragePrincipalOriginAttributes(
|
||||
aChannel, storageOriginAttributes);
|
||||
|
||||
nsTArray<OriginAttributes> originAttributesList;
|
||||
originAttributesList.AppendElement(attrs);
|
||||
originAttributesList.AppendElement(storageOriginAttributes);
|
||||
|
||||
// CHIPS - If CHIPS is enabled the partitioned cookie jar is always available
|
||||
// (and therefore the partitioned OriginAttributes), the unpartitioned cookie
|
||||
// jar is only available in first-party or third-party with storageAccess
|
||||
// contexts.
|
||||
bool isCHIPS = StaticPrefs::network_cookie_cookieBehavior_optInPartitioning();
|
||||
bool isUnpartitioned = storageOriginAttributes.mPartitionKey.IsEmpty();
|
||||
if (isCHIPS && isUnpartitioned) {
|
||||
// Assert that we are only doing this if we are first-party or third-party
|
||||
// with storageAccess.
|
||||
MOZ_ASSERT(
|
||||
!result.contains(ThirdPartyAnalysis::IsForeign) ||
|
||||
result.contains(ThirdPartyAnalysis::IsStorageAccessPermissionGranted));
|
||||
// Add the partitioned principal to principals
|
||||
OriginAttributes partitionedOriginAttributes;
|
||||
StoragePrincipalHelper::GetOriginAttributes(
|
||||
aChannel, partitionedOriginAttributes,
|
||||
StoragePrincipalHelper::ePartitionedPrincipal);
|
||||
originAttributesList.AppendElement(partitionedOriginAttributes);
|
||||
// Assert partitionedOAs have partitioneKey set.
|
||||
MOZ_ASSERT(!partitionedOriginAttributes.mPartitionKey.IsEmpty());
|
||||
}
|
||||
|
||||
for (auto& originAttributes : originAttributesList) {
|
||||
UpdateCookieInContentList(uri, originAttributes);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ support-files = [
|
|||
|
||||
["browser_broadcastChannel.js"]
|
||||
|
||||
["browser_cookie_chips_store_partitioned.js"]
|
||||
["browser_cookie_chips.js"]
|
||||
support-files = ["chips.sjs"]
|
||||
|
||||
["browser_cookie_insecure_overwrites_secure.js"]
|
||||
|
||||
|
|
|
|||
539
netwerk/cookie/test/browser/browser_cookie_chips.js
Normal file
539
netwerk/cookie/test/browser/browser_cookie_chips.js
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_setup(() => {
|
||||
// These are functional and not integration tests, cookieBehavior accept lets
|
||||
// us have StorageAccess on thirparty.
|
||||
Services.prefs.setIntPref(
|
||||
"network.cookie.cookieBehavior",
|
||||
Ci.nsICookieService.BEHAVIOR_ACCEPT
|
||||
);
|
||||
Services.prefs.setBoolPref(
|
||||
"network.cookieJarSettings.unblocked_for_testing",
|
||||
true
|
||||
);
|
||||
Services.prefs.setBoolPref(
|
||||
"network.cookie.cookieBehavior.optInPartitioning",
|
||||
true
|
||||
);
|
||||
Services.prefs.setBoolPref("dom.storage_access.enabled", true);
|
||||
Services.prefs.setBoolPref("dom.storage_access.prompt.testing", true);
|
||||
Services.cookies.removeAll();
|
||||
Services.perms.removeAll();
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("network.cookie.cookieBehavior");
|
||||
Services.prefs.clearUserPref(
|
||||
"network.cookieJarSettings.unblocked_for_testing"
|
||||
);
|
||||
Services.prefs.clearUserPref(
|
||||
"network.cookie.cookieBehavior.optInPartitioning"
|
||||
);
|
||||
Services.prefs.clearUserPref("dom.storage_access.enabled");
|
||||
Services.prefs.clearUserPref("dom.storage_access.prompt.testing");
|
||||
Services.cookies.removeAll();
|
||||
Services.perms.removeAll();
|
||||
});
|
||||
|
||||
const COOKIE_PARTITIONED =
|
||||
"cookie=partitioned; Partitioned; Secure; SameSite=None;";
|
||||
const COOKIE_UNPARTITIONED = "cookie=unpartitioned; Secure; SameSite=None;";
|
||||
|
||||
const PATH = "/browser/netwerk/cookie/test/browser/";
|
||||
const PATH_EMPTY = PATH + "file_empty.html";
|
||||
const HTTP_COOKIE_SET = PATH + "chips.sjs?set";
|
||||
const HTTP_COOKIE_GET = PATH + "chips.sjs?get";
|
||||
|
||||
const FIRST_PARTY = "example.com";
|
||||
const THIRD_PARTY = "example.org";
|
||||
|
||||
const URL_DOCUMENT_FIRSTPARTY = "https://" + FIRST_PARTY + PATH_EMPTY;
|
||||
const URL_DOCUMENT_THIRDPARTY = "https://" + THIRD_PARTY + PATH_EMPTY;
|
||||
const URL_HTTP_FIRSTPARTY = "https://" + FIRST_PARTY + "/" + HTTP_COOKIE_SET;
|
||||
const URL_HTTP_THIRDPARTY = "https://" + THIRD_PARTY + "/" + HTTP_COOKIE_SET;
|
||||
|
||||
function createOriginAttributes(partitionKey) {
|
||||
return JSON.stringify({
|
||||
firstPartyDomain: "",
|
||||
geckoViewSessionContextId: "",
|
||||
inIsolatedMozBrowser: false,
|
||||
partitionKey,
|
||||
privateBrowsingId: 0,
|
||||
userContextId: 0,
|
||||
});
|
||||
}
|
||||
|
||||
function createPartitonKey(url) {
|
||||
let uri = NetUtil.newURI(url);
|
||||
return `(${uri.scheme},${uri.host})`;
|
||||
}
|
||||
|
||||
// OriginAttributes used to access partitioned and unpartitioned cookie jars
|
||||
// in all tests.
|
||||
const partitionedOAs = createOriginAttributes(
|
||||
createPartitonKey(URL_DOCUMENT_FIRSTPARTY)
|
||||
);
|
||||
const unpartitionedOAs = createOriginAttributes("");
|
||||
|
||||
// Set partitioned and unpartitioned cookie from first-party document.
|
||||
// CHIPS "Partitioned" cookie MUST always be stored in partitioned jar.
|
||||
// This calls CookieServiceChild::SetCookieStringFromDocument() internally.
|
||||
// CookieService::SetCookieStringFromDocument() is not explicitly tested since
|
||||
// CHIPS are in the common function CookieCommons::CreateCookieFromDocument().
|
||||
add_task(
|
||||
async function test_chips_store_partitioned_document_first_party_child() {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Set partitioned and unpartitioned cookie from document child-side
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[COOKIE_PARTITIONED, COOKIE_UNPARTITIONED],
|
||||
(partitioned, unpartitioned) => {
|
||||
content.document.cookie = partitioned;
|
||||
content.document.cookie = unpartitioned;
|
||||
}
|
||||
);
|
||||
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
FIRST_PARTY
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
FIRST_PARTY
|
||||
);
|
||||
|
||||
// Assert partitioned/unpartitioned cookie were stored in correct jars
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].value, "partitioned");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].value, "unpartitioned");
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
||||
// Set partitioned and unpartitioned cookie from third-party document with storage
|
||||
// access. CHIPS "Partitioned" cookie MUST always be stored in partitioned jar.
|
||||
// This calls CookieServiceChild::SetCookieStringFromDocument() internally.
|
||||
// CookieService::SetCookieStringFromDocument() is not explicitly tested since
|
||||
// CHIPS are in the common function CookieCommons::CreateCookieFromDocument().
|
||||
add_task(
|
||||
async function test_chips_store_partitioned_document_third_party_storage_access_child() {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Spawn document bc
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[URL_DOCUMENT_THIRDPARTY, COOKIE_PARTITIONED, COOKIE_UNPARTITIONED],
|
||||
async (url, partitioned, unpartitioned) => {
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.src = url;
|
||||
content.document.body.appendChild(ifr);
|
||||
await ContentTaskUtils.waitForEvent(ifr, "load");
|
||||
|
||||
// Spawn iframe bc
|
||||
await SpecialPowers.spawn(
|
||||
await ifr.browsingContext,
|
||||
[partitioned, unpartitioned],
|
||||
async (partitioned, unpartitioned) => {
|
||||
ok(
|
||||
await content.document.hasStorageAccess(),
|
||||
"example.org should have storageAccess by CookieBehavior 0 / test setup"
|
||||
);
|
||||
|
||||
content.document.cookie = partitioned;
|
||||
content.document.cookie = unpartitioned;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
THIRD_PARTY
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
THIRD_PARTY
|
||||
);
|
||||
|
||||
// Assert partitioned/unpartitioned cookie were stored in correct jars
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].value, "partitioned");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].value, "unpartitioned");
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
||||
// Set partitioned and unpartitioned cookie from first-party http load.
|
||||
// CHIPS "Partitioned" cookie MUST always be stored in partitioned jar.
|
||||
// This calls CookieService::SetCookieStringFromHttp() internally.
|
||||
add_task(async function test_chips_store_partitioned_http_first_party_parent() {
|
||||
// Set partitioned and unpartitioned cookie from http parent side through
|
||||
// chips.sjs being loaded.
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_HTTP_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
FIRST_PARTY
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
FIRST_PARTY
|
||||
);
|
||||
|
||||
// Assert partitioned/unpartitioned cookie were stored in correct jars
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].value, "partitioned");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].value, "unpartitioned");
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
});
|
||||
|
||||
// Set partitioned and unpartitioned cookie from third-party http load.
|
||||
// CHIPS "Partitioned" cookie MUST always be stored in partitioned jar.
|
||||
// This calls CookieService::SetCookieStringFromHttp() internally.
|
||||
add_task(
|
||||
async function test_chips_store_partitioned_http_third_party_storage_access_parent() {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Spawn document bc
|
||||
await SpecialPowers.spawn(browser, [URL_HTTP_THIRDPARTY], async url => {
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.src = url;
|
||||
content.document.body.appendChild(ifr);
|
||||
// Send http request with "set" query parameter, partitioned and
|
||||
// unpartitioned cookie will be set through http response from chips.sjs.
|
||||
await ContentTaskUtils.waitForEvent(ifr, "load");
|
||||
|
||||
// Spawn iframe bc
|
||||
await SpecialPowers.spawn(await ifr.browsingContext, [], async () => {
|
||||
ok(
|
||||
await content.document.hasStorageAccess(),
|
||||
"example.org should have storageAccess by CookieBehavior 0 / test setup"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
THIRD_PARTY
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
THIRD_PARTY
|
||||
);
|
||||
|
||||
// Assert partitioned/unpartitioned cookie were stored in correct jars
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].value, "partitioned");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].value, "unpartitioned");
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
||||
// TODO CHIPS - Tests for CookieServiceChild::SetCookieStringFromHttp() need
|
||||
// to be added. Since this is only checkable on onProxyConnectSuccess needs
|
||||
// proxy setup test harness. It is also called after onStartRequest() (Http)
|
||||
// but cookies are already set by the parents
|
||||
// CookieService::SetCookieStringFromHttp() call.
|
||||
|
||||
// Get partitioned and unpartitioned cookies from document (child).
|
||||
// This calls CookieServiceChild::GetCookieStringFromDocument() internally.
|
||||
add_task(
|
||||
async function test_chips_send_partitioned_and_unpartitioned_document_child() {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Spawn document bc
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[COOKIE_PARTITIONED, COOKIE_UNPARTITIONED],
|
||||
async (partitioned, unpartitioned) => {
|
||||
content.document.cookie = partitioned;
|
||||
content.document.cookie = unpartitioned;
|
||||
|
||||
// Assert both unpartitioned and partitioned cookie are returned.
|
||||
let cookies = content.document.cookie;
|
||||
ok(
|
||||
cookies.includes("cookie=partitioned"),
|
||||
"Cookie from partitioned jar was sent."
|
||||
);
|
||||
ok(
|
||||
cookies.includes("cookie=unpartitioned"),
|
||||
"Cookie from unpartitioned jar was sent."
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
||||
// Get partitioned and unpartitioned cookies from document (child) after
|
||||
// storageAccess was granted. This calls CookieServiceChild::TrackCookieLoad()
|
||||
// internally to update child's cookies.
|
||||
add_task(
|
||||
async function test_chips_send_partitioned_and_unpartitioned_on_storage_access_child() {
|
||||
// Set cookieBehavior to BEHAVIOR_REJECT_TRACKERS_AND_PARTITION_FOREIGN for
|
||||
// requestStorageAccess() based test.
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", 5);
|
||||
|
||||
// Set example.org first-party unpartitioned cookie
|
||||
await BrowserTestUtils.withNewTab(
|
||||
URL_DOCUMENT_THIRDPARTY,
|
||||
async browser => {
|
||||
info("Set a first party cookie via `document.cookie`.");
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[COOKIE_UNPARTITIONED],
|
||||
async unpartitioned => {
|
||||
content.document.cookie = unpartitioned;
|
||||
is(
|
||||
content.document.cookie,
|
||||
"cookie=unpartitioned",
|
||||
"Unpartitioned cookie was set."
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Assert cookie was set on parent cookie service for example.org.
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
THIRD_PARTY
|
||||
);
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].value, "unpartitioned");
|
||||
|
||||
// Load example.com as first-party in tab
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Set third-party cookie from example.org iframe, get storageAccess and
|
||||
// check cookies.
|
||||
// Spawn document bc
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[URL_DOCUMENT_THIRDPARTY, COOKIE_PARTITIONED],
|
||||
async (url, partitioned) => {
|
||||
// Create third-party iframe
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.src = url;
|
||||
content.document.body.appendChild(ifr);
|
||||
await ContentTaskUtils.waitForEvent(ifr, "load");
|
||||
|
||||
// Spawn iframe bc
|
||||
await SpecialPowers.spawn(
|
||||
await ifr.browsingContext,
|
||||
[partitioned],
|
||||
async partitioned => {
|
||||
ok(
|
||||
!(await content.document.hasStorageAccess()),
|
||||
"example.org should not have storageAccess initially."
|
||||
);
|
||||
|
||||
// Set a partitioned third-party cookie and assert its the only.
|
||||
content.document.cookie = partitioned;
|
||||
is(
|
||||
content.document.cookie,
|
||||
"cookie=partitioned",
|
||||
"Partitioned cookie was set."
|
||||
);
|
||||
|
||||
info("Simulate user activation.");
|
||||
SpecialPowers.wrap(content.document).notifyUserGestureActivation();
|
||||
|
||||
info("Request storage access.");
|
||||
await content.document.requestStorageAccess();
|
||||
|
||||
ok(
|
||||
await content.document.hasStorageAccess(),
|
||||
"example.org should now have storageAccess."
|
||||
);
|
||||
|
||||
// Assert both unpartitioned and partitioned cookie are returned.
|
||||
let cookies = content.document.cookie;
|
||||
ok(
|
||||
cookies.includes("cookie=partitioned"),
|
||||
"Cookie from partitioned jar was sent."
|
||||
);
|
||||
ok(
|
||||
cookies.includes("cookie=unpartitioned"),
|
||||
"Cookie from unpartitioned jar was sent."
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
Services.perms.removeAll();
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
|
||||
}
|
||||
);
|
||||
|
||||
// Set partitioned and unpartitioned cookies for URL_DOCUMENT_FIRSTPARTY, then
|
||||
// load URL again, assure cookies are correctly send to content child process.
|
||||
// This tests CookieServiceParent::TrackCookieLoad() internally.
|
||||
add_task(
|
||||
async function test_chips_send_partitioned_and_unpartitioned_document_parent() {
|
||||
// Set example.com first-party unpartitioned and partitioned cookie, then
|
||||
// close tab.
|
||||
await BrowserTestUtils.withNewTab(
|
||||
URL_DOCUMENT_FIRSTPARTY,
|
||||
async browser => {
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[COOKIE_PARTITIONED, COOKIE_UNPARTITIONED],
|
||||
async (partitioned, unpartitioned) => {
|
||||
content.document.cookie = unpartitioned;
|
||||
content.document.cookie = partitioned;
|
||||
let cookies = content.document.cookie;
|
||||
ok(
|
||||
cookies.includes("cookie=unpartitioned"),
|
||||
"Unpartitioned cookie was set."
|
||||
);
|
||||
ok(
|
||||
cookies.includes("cookie=partitioned"),
|
||||
"Partitioned cookie was set."
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Assert we have one partitioned and one unpartitioned cookie set.
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
FIRST_PARTY
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
FIRST_PARTY
|
||||
);
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].value, "partitioned");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].value, "unpartitioned");
|
||||
|
||||
// Reload example.com and assert previously set cookies are correctly
|
||||
// send to content child document.
|
||||
await BrowserTestUtils.withNewTab(
|
||||
URL_DOCUMENT_FIRSTPARTY,
|
||||
async browser => {
|
||||
await SpecialPowers.spawn(browser, [], () => {
|
||||
let cookies = content.document.cookie;
|
||||
ok(
|
||||
cookies.includes("cookie=unpartitioned"),
|
||||
"Unpartitioned cookie was sent."
|
||||
);
|
||||
ok(
|
||||
cookies.includes("cookie=partitioned"),
|
||||
"Partitioned cookie was sent."
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Cleanup
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
||||
// Set partitioned and unpartitioned cookies for URL_DOCUMENT_FIRSTPARTY, then
|
||||
// send http request, assure cookies are correctly send in "Cookie" header.
|
||||
// This tests CookieService::GetCookieStringFromHttp() internally.
|
||||
add_task(
|
||||
async function test_chips_send_partitioned_and_unpartitioned_http_parent() {
|
||||
// Load empty document.
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[HTTP_COOKIE_SET, HTTP_COOKIE_GET],
|
||||
async (set, get) => {
|
||||
// Send http request with "set" query parameter, partitioned and
|
||||
// unpartitioned cookie will be set through http response.
|
||||
await content.fetch(set);
|
||||
|
||||
// Assert cookies were set to document.
|
||||
let cookies = content.document.cookie;
|
||||
ok(
|
||||
cookies.includes("cookie=unpartitioned"),
|
||||
"Unpartitioned cookie was set to document."
|
||||
);
|
||||
ok(
|
||||
cookies.includes("cookie=partitioned"),
|
||||
"Partitioned cookie was set to document."
|
||||
);
|
||||
|
||||
// Send http request with "get" query parameter, chips.sjs will return
|
||||
// the request "Cookie" header string.
|
||||
await content
|
||||
.fetch(get)
|
||||
.then(response => response.text())
|
||||
.then(requestCookies => {
|
||||
// Assert cookies were sent in http request.
|
||||
ok(
|
||||
requestCookies.includes("cookie=unpartitioned"),
|
||||
"Unpartitioned cookie was sent in http request."
|
||||
);
|
||||
ok(
|
||||
requestCookies.includes("cookie=partitioned"),
|
||||
"Partitioned cookie was sent in http request."
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
|
@ -1,260 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_setup(async => {
|
||||
// These are functional and not integration tests, cookieBehavior accept lets
|
||||
// us have StorageAccess on thirparty.
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
|
||||
Services.prefs.setBoolPref(
|
||||
"network.cookieJarSettings.unblocked_for_testing",
|
||||
true
|
||||
);
|
||||
Services.prefs.setBoolPref(
|
||||
"network.cookie.cookieBehavior.optInPartitioning",
|
||||
true
|
||||
);
|
||||
Services.prefs.setBoolPref("dom.storage_access.enabled", true);
|
||||
Services.cookies.removeAll();
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("network.cookie.cookieBehavior");
|
||||
Services.prefs.clearUserPref(
|
||||
"network.cookieJarSettings.unblocked_for_testing"
|
||||
);
|
||||
Services.prefs.clearUserPref(
|
||||
"network.cookie.cookieBehavior.optInPartitioning"
|
||||
);
|
||||
Services.prefs.clearUserPref("dom.storage_access.enabled");
|
||||
Services.cookies.removeAll();
|
||||
});
|
||||
|
||||
const COOKIE_PARTITIONED = "part=value; Partitioned; Secure; SameSite=None;";
|
||||
const COOKIE_UNPARTITIONED = "unpart=value; Secure; SameSite=None;";
|
||||
|
||||
const pathEmpty = "/browser/netwerk/cookie/test/browser/file_empty.html";
|
||||
const pathCookie = "/browser/netwerk/cookie/test/browser/partitioned.sjs";
|
||||
const firstParty = "example.com";
|
||||
const thirdParty = "example.org";
|
||||
|
||||
const URL_DOCUMENT_FIRSTPARTY = "https://" + firstParty + pathEmpty;
|
||||
const URL_DOCUMENT_THIRDPARTY = "https://" + thirdParty + pathEmpty;
|
||||
|
||||
const URL_HTTP_FIRSTPARTY = "https://" + firstParty + pathCookie;
|
||||
const URL_HTTP_THIRDPARTY = "https://" + thirdParty + pathCookie;
|
||||
|
||||
function createOriginAttributes(partitionKey) {
|
||||
return JSON.stringify({
|
||||
firstPartyDomain: "",
|
||||
geckoViewSessionContextId: "",
|
||||
inIsolatedMozBrowser: false,
|
||||
partitionKey,
|
||||
privateBrowsingId: 0,
|
||||
userContextId: 0,
|
||||
});
|
||||
}
|
||||
|
||||
function createPartitonKey(url) {
|
||||
let uri = NetUtil.newURI(URL_DOCUMENT_FIRSTPARTY);
|
||||
return `(${uri.scheme},${uri.host})`;
|
||||
}
|
||||
|
||||
// OriginAttributes used to access partitioned and unpartitioned cookie jars
|
||||
// in all tests.
|
||||
const partitionedOAs = createOriginAttributes(
|
||||
createPartitonKey(URL_DOCUMENT_FIRSTPARTY)
|
||||
);
|
||||
const unpartitionedOAs = createOriginAttributes("");
|
||||
|
||||
// Set partitioned and unpartitioned cookie from first-party document.
|
||||
// CHIPS "Partitioned" cookie MUST always be stored in partitioned jar.
|
||||
// This calls CookieServiceChild::SetCookieStringFromDocument() internally
|
||||
// CookieService::SetCookieStringFromDocument() is not explicitly tested since
|
||||
// CHIPS are in the common function CookieCommons::CreateCookieFromDocument().
|
||||
add_task(
|
||||
async function test_chips_store_partitioned_document_first_party_child() {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Set partitioned and unpartitioned cookie from document child-side
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[COOKIE_PARTITIONED, COOKIE_UNPARTITIONED],
|
||||
(partitioned, unpartitioned) => {
|
||||
content.document.cookie = partitioned;
|
||||
content.document.cookie = unpartitioned;
|
||||
}
|
||||
);
|
||||
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
firstParty
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
firstParty
|
||||
);
|
||||
|
||||
// Assert partitioned/unpartitioned cookie were stored in correct jars
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].name, "part");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].name, "unpart");
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
||||
// Set partitioned and unpartitioned cookie from third-party document with storage
|
||||
// access. CHIPS "Partitioned" cookie MUST always be stored in partitioned jar.
|
||||
// This calls CookieServiceChild::SetCookieStringFromDocument() internally
|
||||
// CookieService::SetCookieStringFromDocument() is not explicitly tested since
|
||||
// CHIPS are in the common function CookieCommons::CreateCookieFromDocument().
|
||||
add_task(
|
||||
async function test_chips_store_partitioned_document_third_party_storage_access_child() {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Spawn document bc
|
||||
await SpecialPowers.spawn(
|
||||
browser,
|
||||
[URL_DOCUMENT_THIRDPARTY, COOKIE_PARTITIONED, COOKIE_UNPARTITIONED],
|
||||
async (url, partitioned, unpartitioned) => {
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.src = url;
|
||||
content.document.body.appendChild(ifr);
|
||||
await ContentTaskUtils.waitForEvent(ifr, "load");
|
||||
|
||||
// Spawn iframe bc
|
||||
await SpecialPowers.spawn(
|
||||
await ifr.browsingContext,
|
||||
[partitioned, unpartitioned],
|
||||
async (partitioned, unpartitioned) => {
|
||||
ok(
|
||||
await content.document.hasStorageAccess(),
|
||||
"example.org should have storageAccess by CookieBehavior 0 / test setup"
|
||||
);
|
||||
|
||||
content.document.cookie = partitioned;
|
||||
content.document.cookie = unpartitioned;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
thirdParty
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
thirdParty
|
||||
);
|
||||
|
||||
// Assert partitioned/unpartitioned cookie were stored in correct jars
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].name, "part");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].name, "unpart");
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
||||
// Set partitioned and unpartitioned cookie from first-party http load.
|
||||
// CHIPS "Partitioned" cookie MUST always be stored in partitioned jar.
|
||||
// This calls CookieService::SetCookieStringFromHttp() internally.
|
||||
add_task(async function test_chips_store_partitioned_http_first_party_parent() {
|
||||
// Set partitioned and unpartitioned cookie from http parent side through
|
||||
// partitoned.sjs being loaded
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_HTTP_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
firstParty
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
firstParty
|
||||
);
|
||||
|
||||
// Assert partitioned/unpartitioned cookie were stored in correct jars
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].name, "b");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].name, "a");
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
});
|
||||
|
||||
// Set partitioned and unpartitioned cookie from third-party http load.
|
||||
// CHIPS "Partitioned" cookie MUST always be stored in partitioned jar.
|
||||
// This calls CookieService::SetCookieStringFromHttp() internally.
|
||||
add_task(
|
||||
async function test_chips_store_partitioned_http_third_party_storage_access_parent() {
|
||||
const tab = BrowserTestUtils.addTab(gBrowser, URL_DOCUMENT_FIRSTPARTY);
|
||||
const browser = gBrowser.getBrowserForTab(tab);
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
// Spawn document bc
|
||||
await SpecialPowers.spawn(browser, [URL_HTTP_THIRDPARTY], async url => {
|
||||
let ifr = content.document.createElement("iframe");
|
||||
ifr.src = url;
|
||||
content.document.body.appendChild(ifr);
|
||||
// Set partitioned and unpartitioned cookie from http parent side through
|
||||
// partitoned.sjs being loaded
|
||||
await ContentTaskUtils.waitForEvent(ifr, "load");
|
||||
|
||||
// Spawn iframe bc
|
||||
await SpecialPowers.spawn(await ifr.browsingContext, [], async () => {
|
||||
ok(
|
||||
await content.document.hasStorageAccess(),
|
||||
"example.org should have storageAccess by CookieBehavior 0 / test setup"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Get cookies from partitioned jar
|
||||
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
partitionedOAs,
|
||||
thirdParty
|
||||
);
|
||||
// Get cookies from unpartitioned jar
|
||||
let unpartitioned = Services.cookies.getCookiesWithOriginAttributes(
|
||||
unpartitionedOAs,
|
||||
thirdParty
|
||||
);
|
||||
|
||||
// Assert partitioned/unpartitioned cookie were stored in correct jars
|
||||
Assert.equal(partitioned.length, 1);
|
||||
Assert.equal(partitioned[0].name, "b");
|
||||
Assert.equal(unpartitioned.length, 1);
|
||||
Assert.equal(unpartitioned[0].name, "a");
|
||||
|
||||
// Cleanup
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.cookies.removeAll();
|
||||
}
|
||||
);
|
||||
|
||||
// TODO CHIPS - Tests for CookieServiceChild::SetCookieStringFromHttp() need
|
||||
// to be added. Since this only called on onProxyConnectSuccess needs proxy
|
||||
// setup harness.
|
||||
28
netwerk/cookie/test/browser/chips.sjs
Normal file
28
netwerk/cookie/test/browser/chips.sjs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
function handleRequest(aRequest, aResponse) {
|
||||
aResponse.setStatusLine(aRequest.httpVersion, 200);
|
||||
|
||||
var params = new URLSearchParams(aRequest.queryString);
|
||||
|
||||
// Get Cookie header string.
|
||||
if (params.has("get")) {
|
||||
if (aRequest.hasHeader("Cookie")) {
|
||||
let cookie = aRequest.getHeader("Cookie");
|
||||
aResponse.write(cookie);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Set a partitioned and a unpartitioned cookie.
|
||||
if (params.has("set")) {
|
||||
aResponse.setHeader(
|
||||
"Set-Cookie",
|
||||
"cookie=partitioned; Partitioned; SameSite=None; Secure",
|
||||
true
|
||||
);
|
||||
aResponse.setHeader(
|
||||
"Set-Cookie",
|
||||
"cookie=unpartitioned; SameSite=None; Secure",
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue