Bug 1876574 - Add SameSite bit to partition-key origin attribute for first-party partitioning - r=timhuang
This patch is a no-op for observable functionality. All it does is add a bit to the partitionKey for OA, and then adds plumbing to be able to set it, and where it is required, sets it to false. This is serialized identically to the absence of the bit, so nothing changes at all. Differential Revision: https://phabricator.services.mozilla.com/D203155
This commit is contained in:
@@ -22,8 +22,8 @@ static const char kSanitizedChar = '+';
|
||||
namespace mozilla {
|
||||
|
||||
static void MakeTopLevelInfo(const nsACString& aScheme, const nsACString& aHost,
|
||||
int32_t aPort, bool aUseSite,
|
||||
nsAString& aTopLevelInfo) {
|
||||
int32_t aPort, bool aForeignByAncestorContext,
|
||||
bool aUseSite, nsAString& aTopLevelInfo) {
|
||||
if (!aUseSite) {
|
||||
aTopLevelInfo.Assign(NS_ConvertUTF8toUTF16(aHost));
|
||||
return;
|
||||
@@ -41,19 +41,26 @@ static void MakeTopLevelInfo(const nsACString& aScheme, const nsACString& aHost,
|
||||
site.Append(",");
|
||||
site.AppendInt(aPort);
|
||||
}
|
||||
if (aForeignByAncestorContext) {
|
||||
site.Append(",f");
|
||||
}
|
||||
site.AppendLiteral(")");
|
||||
|
||||
aTopLevelInfo.Assign(NS_ConvertUTF8toUTF16(site));
|
||||
}
|
||||
|
||||
static void MakeTopLevelInfo(const nsACString& aScheme, const nsACString& aHost,
|
||||
bool aUseSite, nsAString& aTopLevelInfo) {
|
||||
MakeTopLevelInfo(aScheme, aHost, -1, aUseSite, aTopLevelInfo);
|
||||
bool aForeignByAncestorContext, bool aUseSite,
|
||||
nsAString& aTopLevelInfo) {
|
||||
MakeTopLevelInfo(aScheme, aHost, -1, aForeignByAncestorContext, aUseSite,
|
||||
aTopLevelInfo);
|
||||
}
|
||||
|
||||
static void PopulateTopLevelInfoFromURI(const bool aIsTopLevelDocument,
|
||||
nsIURI* aURI, bool aIsFirstPartyEnabled,
|
||||
bool aForced, bool aUseSite,
|
||||
nsIURI* aURI,
|
||||
bool aForeignByAncestorContext,
|
||||
bool aIsFirstPartyEnabled, bool aForced,
|
||||
bool aUseSite,
|
||||
nsString OriginAttributes::*aTarget,
|
||||
OriginAttributes& aOriginAttributes) {
|
||||
nsresult rv;
|
||||
@@ -86,7 +93,7 @@ static void PopulateTopLevelInfoFromURI(const bool aIsTopLevelDocument,
|
||||
|
||||
if (scheme.EqualsLiteral("about")) {
|
||||
MakeTopLevelInfo(scheme, nsLiteralCString(ABOUT_URI_FIRST_PARTY_DOMAIN),
|
||||
aUseSite, topLevelInfo);
|
||||
aForeignByAncestorContext, aUseSite, topLevelInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -128,7 +135,8 @@ static void PopulateTopLevelInfoFromURI(const bool aIsTopLevelDocument,
|
||||
nsAutoCString baseDomain;
|
||||
rv = tldService->GetBaseDomain(uri, 0, baseDomain);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MakeTopLevelInfo(scheme, baseDomain, aUseSite, topLevelInfo);
|
||||
MakeTopLevelInfo(scheme, baseDomain, aForeignByAncestorContext, aUseSite,
|
||||
topLevelInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -160,12 +168,14 @@ static void PopulateTopLevelInfoFromURI(const bool aIsTopLevelDocument,
|
||||
ipAddr = host;
|
||||
}
|
||||
|
||||
MakeTopLevelInfo(scheme, ipAddr, port, aUseSite, topLevelInfo);
|
||||
MakeTopLevelInfo(scheme, ipAddr, port, aForeignByAncestorContext, aUseSite,
|
||||
topLevelInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aUseSite) {
|
||||
MakeTopLevelInfo(scheme, host, port, aUseSite, topLevelInfo);
|
||||
MakeTopLevelInfo(scheme, host, port, aForeignByAncestorContext, aUseSite,
|
||||
topLevelInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -173,7 +183,8 @@ static void PopulateTopLevelInfoFromURI(const bool aIsTopLevelDocument,
|
||||
nsAutoCString publicSuffix;
|
||||
rv = tldService->GetPublicSuffix(uri, publicSuffix);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MakeTopLevelInfo(scheme, publicSuffix, port, aUseSite, topLevelInfo);
|
||||
MakeTopLevelInfo(scheme, publicSuffix, port, aForeignByAncestorContext,
|
||||
aUseSite, topLevelInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -182,7 +193,7 @@ static void PopulateTopLevelInfoFromURI(const bool aIsTopLevelDocument,
|
||||
void OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
nsIURI* aURI, bool aForced) {
|
||||
PopulateTopLevelInfoFromURI(
|
||||
aIsTopLevelDocument, aURI, IsFirstPartyEnabled(), aForced,
|
||||
aIsTopLevelDocument, aURI, false, IsFirstPartyEnabled(), aForced,
|
||||
StaticPrefs::privacy_firstparty_isolate_use_site(),
|
||||
&OriginAttributes::mFirstPartyDomain, *this);
|
||||
}
|
||||
@@ -203,19 +214,21 @@ void OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
mFirstPartyDomain = aDomain;
|
||||
}
|
||||
|
||||
void OriginAttributes::SetPartitionKey(nsIURI* aURI) {
|
||||
void OriginAttributes::SetPartitionKey(nsIURI* aURI,
|
||||
bool aForeignByAncestorContext) {
|
||||
PopulateTopLevelInfoFromURI(
|
||||
false /* aIsTopLevelDocument */, aURI, IsFirstPartyEnabled(),
|
||||
true /* aForced */, StaticPrefs::privacy_dynamic_firstparty_use_site(),
|
||||
false /* aIsTopLevelDocument */, aURI, aForeignByAncestorContext,
|
||||
IsFirstPartyEnabled(), true /* aForced */,
|
||||
StaticPrefs::privacy_dynamic_firstparty_use_site(),
|
||||
&OriginAttributes::mPartitionKey, *this);
|
||||
}
|
||||
|
||||
void OriginAttributes::SetPartitionKey(const nsACString& aDomain) {
|
||||
SetPartitionKey(NS_ConvertUTF8toUTF16(aDomain));
|
||||
void OriginAttributes::SetPartitionKey(const nsACString& aOther) {
|
||||
SetPartitionKey(NS_ConvertUTF8toUTF16(aOther));
|
||||
}
|
||||
|
||||
void OriginAttributes::SetPartitionKey(const nsAString& aDomain) {
|
||||
mPartitionKey = aDomain;
|
||||
void OriginAttributes::SetPartitionKey(const nsAString& aOther) {
|
||||
mPartitionKey = aOther;
|
||||
}
|
||||
|
||||
void OriginAttributes::CreateSuffix(nsACString& aStr) const {
|
||||
@@ -419,17 +432,20 @@ bool OriginAttributes::IsPrivateBrowsing(const nsACString& aOrigin) {
|
||||
bool OriginAttributes::ParsePartitionKey(const nsAString& aPartitionKey,
|
||||
nsAString& outScheme,
|
||||
nsAString& outBaseDomain,
|
||||
int32_t& outPort) {
|
||||
int32_t& outPort,
|
||||
bool& outForeignByAncestorContext) {
|
||||
outScheme.Truncate();
|
||||
outBaseDomain.Truncate();
|
||||
outPort = -1;
|
||||
outForeignByAncestorContext = false;
|
||||
|
||||
// Partition keys have the format "(<scheme>,<baseDomain>,[port])". The port
|
||||
// is optional. For example: "(https,example.com,8443)" or
|
||||
// "(http,example.org)".
|
||||
// When privacy.dynamic_firstparty.use_site = false, the partitionKey contains
|
||||
// only the host, e.g. "example.com".
|
||||
// See MakeTopLevelInfo for the partitionKey serialization code.
|
||||
// Partition keys have the format
|
||||
// "(<scheme>,<baseDomain>[,port][,foreignancestorbit])". The port and
|
||||
// ancestor bits are optional. For example: "(https,example.com,8443)" or
|
||||
// "(http,example.org)", or "(http,example.info,f)", or
|
||||
// "(http,example.biz,8443,f)". When privacy.dynamic_firstparty.use_site =
|
||||
// false, the partitionKey contains only the host, e.g. "example.com". See
|
||||
// MakeTopLevelInfo for the partitionKey serialization code.
|
||||
|
||||
if (aPartitionKey.IsEmpty()) {
|
||||
return true;
|
||||
@@ -466,6 +482,10 @@ bool OriginAttributes::ParsePartitionKey(const nsAString& aPartitionKey,
|
||||
} else if (fieldIndex == 1) {
|
||||
outBaseDomain.Assign(field);
|
||||
} else if (fieldIndex == 2) {
|
||||
// The first optional argument is either "f" or a port number
|
||||
if (field.EqualsLiteral("f")) {
|
||||
outForeignByAncestorContext = true;
|
||||
} else {
|
||||
// Parse the port which is represented in the partitionKey string as a
|
||||
// decimal (base 10) number.
|
||||
long port = strtol(NS_ConvertUTF16toUTF8(field).get(), nullptr, 10);
|
||||
@@ -474,6 +494,15 @@ bool OriginAttributes::ParsePartitionKey(const nsAString& aPartitionKey,
|
||||
return false;
|
||||
}
|
||||
outPort = static_cast<int32_t>(port);
|
||||
}
|
||||
} else if (fieldIndex == 3) {
|
||||
// The second optional argument, if it exists, is "f" and the first
|
||||
// optional argument was a port
|
||||
if (field.EqualsLiteral("f") || outPort == -1) {
|
||||
NS_WARNING("Invalid partitionKey. Invalid token.");
|
||||
return false;
|
||||
}
|
||||
outForeignByAncestorContext = true;
|
||||
} else {
|
||||
NS_WARNING("Invalid partitionKey. Too many tokens");
|
||||
return false;
|
||||
|
||||
@@ -27,9 +27,9 @@ class OriginAttributes : public dom::OriginAttributesDictionary {
|
||||
void SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
const nsAString& aDomain, bool aForced = false);
|
||||
|
||||
void SetPartitionKey(nsIURI* aURI);
|
||||
void SetPartitionKey(const nsACString& aDomain);
|
||||
void SetPartitionKey(const nsAString& aDomain);
|
||||
void SetPartitionKey(nsIURI* aURI, bool aForeignByAncestorContext);
|
||||
void SetPartitionKey(const nsACString& aOther);
|
||||
void SetPartitionKey(const nsAString& aOther);
|
||||
|
||||
enum {
|
||||
STRIP_FIRST_PARTY_DOMAIN = 0x01,
|
||||
@@ -129,13 +129,13 @@ class OriginAttributes : public dom::OriginAttributesDictionary {
|
||||
// different than 0.
|
||||
static bool IsPrivateBrowsing(const nsACString& aOrigin);
|
||||
|
||||
// Parse a partitionKey of the format "(<scheme>,<baseDomain>,[port])" into
|
||||
// its components.
|
||||
// Returns false if the partitionKey cannot be parsed because the format is
|
||||
// invalid.
|
||||
// Parse a partitionKey of the format
|
||||
// "(<scheme>,<baseDomain>,[port],[ancestorbit])" into its components. Returns
|
||||
// false if the partitionKey cannot be parsed because the format is invalid.
|
||||
static bool ParsePartitionKey(const nsAString& aPartitionKey,
|
||||
nsAString& outScheme, nsAString& outBaseDomain,
|
||||
int32_t& outPort);
|
||||
int32_t& outPort,
|
||||
bool& outForeignByAncestorContext);
|
||||
};
|
||||
|
||||
class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary {
|
||||
@@ -193,8 +193,9 @@ class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary {
|
||||
nsString scheme;
|
||||
nsString baseDomain;
|
||||
int32_t port;
|
||||
bool ancestor;
|
||||
bool success = OriginAttributes::ParsePartitionKey(
|
||||
aAttrs.mPartitionKey, scheme, baseDomain, port);
|
||||
aAttrs.mPartitionKey, scheme, baseDomain, port, ancestor);
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
@@ -210,6 +211,10 @@ class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary {
|
||||
if (pkPattern.mPort.WasPassed() && pkPattern.mPort.Value() != port) {
|
||||
return false;
|
||||
}
|
||||
if (pkPattern.mForeignByAncestorContext.WasPassed() &&
|
||||
pkPattern.mForeignByAncestorContext.Value() != ancestor) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,6 +267,12 @@ class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary {
|
||||
self.mPort.Value() != other.mPort.Value()) {
|
||||
return false;
|
||||
}
|
||||
if (self.mForeignByAncestorContext.WasPassed() &&
|
||||
other.mForeignByAncestorContext.WasPassed() &&
|
||||
self.mForeignByAncestorContext.Value() !=
|
||||
other.mForeignByAncestorContext.Value()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1289,9 +1289,10 @@ void ChromeUtils::GetBaseDomainFromPartitionKey(dom::GlobalObject& aGlobal,
|
||||
nsString scheme;
|
||||
nsString pkBaseDomain;
|
||||
int32_t port;
|
||||
bool ancestor;
|
||||
|
||||
if (!mozilla::OriginAttributes::ParsePartitionKey(aPartitionKey, scheme,
|
||||
pkBaseDomain, port)) {
|
||||
if (!mozilla::OriginAttributes::ParsePartitionKey(
|
||||
aPartitionKey, scheme, pkBaseDomain, port, ancestor)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
@@ -1317,7 +1318,10 @@ void ChromeUtils::GetPartitionKeyFromURL(dom::GlobalObject& aGlobal,
|
||||
}
|
||||
|
||||
mozilla::OriginAttributes attrs;
|
||||
attrs.SetPartitionKey(uri);
|
||||
// For now, uses assume the partition key is cross-site.
|
||||
// We will need to not make this assumption to allow access
|
||||
// to same-site partitioned cookies in the cookie extension API.
|
||||
attrs.SetPartitionKey(uri, false);
|
||||
|
||||
aPartitionKey = attrs.mPartitionKey;
|
||||
}
|
||||
|
||||
@@ -975,6 +975,7 @@ dictionary PartitionKeyPatternDictionary {
|
||||
DOMString scheme;
|
||||
DOMString baseDomain;
|
||||
long port;
|
||||
boolean foreignByAncestorContext;
|
||||
};
|
||||
|
||||
dictionary CompileScriptOptionsDictionary {
|
||||
|
||||
@@ -544,10 +544,11 @@ nsresult ServiceWorkerPrivate::Initialize() {
|
||||
nsAutoString scheme;
|
||||
nsAutoString pkBaseDomain;
|
||||
int32_t unused;
|
||||
bool unused2;
|
||||
|
||||
if (OriginAttributes::ParsePartitionKey(
|
||||
principal->OriginAttributesRef().mPartitionKey, scheme,
|
||||
pkBaseDomain, unused)) {
|
||||
pkBaseDomain, unused, unused2)) {
|
||||
nsCOMPtr<nsIURI> firstPartyURI;
|
||||
rv = NS_NewURI(getter_AddRefs(firstPartyURI),
|
||||
scheme + u"://"_ns + pkBaseDomain);
|
||||
@@ -592,7 +593,8 @@ nsresult ServiceWorkerPrivate::Initialize() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri);
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)
|
||||
->SetPartitionKey(uri, false);
|
||||
|
||||
// The service worker is for a first-party context, we can use the uri of
|
||||
// the service worker as the first-party domain to get the fingerprinting
|
||||
|
||||
@@ -678,7 +678,8 @@ nsresult CompareNetwork::Initialize(nsIPrincipal* aPrincipal,
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)
|
||||
->SetPartitionKey(aPrincipal->OriginAttributesRef().mPartitionKey);
|
||||
} else {
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri);
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)
|
||||
->SetPartitionKey(uri, false);
|
||||
}
|
||||
|
||||
// Note that because there is no "serviceworker" RequestContext type, we can
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "mozilla/PermissionManager.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/StoragePrincipalHelper.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
|
||||
@@ -196,7 +197,7 @@ CookieJarSettings::InitWithURI(nsIURI* aURI, bool aIsPrivate) {
|
||||
|
||||
mCookieBehavior = nsICookieManager::GetCookieBehavior(aIsPrivate);
|
||||
|
||||
SetPartitionKey(aURI);
|
||||
SetPartitionKey(aURI, false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -526,14 +527,26 @@ void CookieJarSettings::Merge(const CookieJarSettingsArgs& aData) {
|
||||
}
|
||||
}
|
||||
|
||||
void CookieJarSettings::SetPartitionKey(nsIURI* aURI) {
|
||||
void CookieJarSettings::SetPartitionKey(nsIURI* aURI,
|
||||
bool aForeignByAncestorContext) {
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
OriginAttributes attrs;
|
||||
attrs.SetPartitionKey(aURI);
|
||||
attrs.SetPartitionKey(aURI, aForeignByAncestorContext);
|
||||
mPartitionKey = std::move(attrs.mPartitionKey);
|
||||
}
|
||||
|
||||
void CookieJarSettings::UpdatePartitionKeyForDocumentLoadedByChannel(
|
||||
nsIChannel* aChannel) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
|
||||
bool foreignByAncestorContext =
|
||||
false; // Bug 1876575 will change this to
|
||||
// loadInfo->GetIsInThirdPartyContext() &&
|
||||
// !loadInfo->GetIsThirdPartyContextToTopWindow();
|
||||
StoragePrincipalHelper::UpdatePartitionKeyWithForeignAncestorBit(
|
||||
mPartitionKey, foreignByAncestorContext);
|
||||
}
|
||||
|
||||
void CookieJarSettings::UpdateIsOnContentBlockingAllowList(
|
||||
nsIChannel* aChannel) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
@@ -161,12 +161,14 @@ class CookieJarSettings final : public nsICookieJarSettings {
|
||||
|
||||
void UpdateIsOnContentBlockingAllowList(nsIChannel* aChannel);
|
||||
|
||||
void SetPartitionKey(nsIURI* aURI);
|
||||
void SetPartitionKey(nsIURI* aURI, bool aForeignByAncestorContext);
|
||||
void SetPartitionKey(const nsAString& aPartitionKey) {
|
||||
mPartitionKey = aPartitionKey;
|
||||
}
|
||||
const nsAString& GetPartitionKey() { return mPartitionKey; };
|
||||
|
||||
void UpdatePartitionKeyForDocumentLoadedByChannel(nsIChannel* aChannel);
|
||||
|
||||
void SetFingerprintingRandomizationKey(const nsTArray<uint8_t>& aKey) {
|
||||
mFingerprintingRandomKey.reset();
|
||||
|
||||
|
||||
@@ -2423,7 +2423,6 @@ HttpBaseChannel::GetDocumentURI(nsIURI** aDocumentURI) {
|
||||
NS_IMETHODIMP
|
||||
HttpBaseChannel::SetDocumentURI(nsIURI* aDocumentURI) {
|
||||
ENSURE_CALLED_BEFORE_CONNECT();
|
||||
|
||||
mDocumentURI = aDocumentURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -1009,6 +1009,14 @@ void AntiTrackingUtils::UpdateAntiTrackingInfoForChannel(nsIChannel* aChannel) {
|
||||
->MarkOverriddenFingerprintingSettingsAsSet();
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
|
||||
Unused << loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
|
||||
// For subdocuments, the channel's partition key is that of the parent
|
||||
// document. This document may have a different partition key, particularly
|
||||
// one without the same-site bit.
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)
|
||||
->UpdatePartitionKeyForDocumentLoadedByChannel(aChannel);
|
||||
|
||||
// We only update the IsOnContentBlockingAllowList flag and the partition key
|
||||
// for the top-level http channel.
|
||||
//
|
||||
@@ -1024,9 +1032,6 @@ void AntiTrackingUtils::UpdateAntiTrackingInfoForChannel(nsIChannel* aChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
|
||||
Unused << loadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
|
||||
|
||||
// Update the IsOnContentBlockingAllowList flag in the CookieJarSettings
|
||||
// if this is a top level loading. For sub-document loading, this flag
|
||||
// would inherit from the parent.
|
||||
@@ -1037,7 +1042,7 @@ void AntiTrackingUtils::UpdateAntiTrackingInfoForChannel(nsIChannel* aChannel) {
|
||||
// propagated to non-top level loads via CookieJarSetting.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
Unused << aChannel->GetURI(getter_AddRefs(uri));
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri);
|
||||
net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri, false);
|
||||
|
||||
// Generate the fingerprinting randomization key for top-level loads. The key
|
||||
// will automatically be propagated to sub loads.
|
||||
|
||||
@@ -86,8 +86,11 @@ bool ChooseOriginAttributes(nsIChannel* aChannel, OriginAttributes& aAttrs,
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aAttrs.SetPartitionKey(principalURI);
|
||||
bool foreignByAncestorContext =
|
||||
false; // Bug 1876575 will change this to
|
||||
// loadInfo->GetIsInThirdPartyContext() &&
|
||||
// !loadInfo->GetIsThirdPartyContextToTopWindow();
|
||||
aAttrs.SetPartitionKey(principalURI, foreignByAncestorContext);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -560,7 +563,7 @@ void StoragePrincipalHelper::UpdateOriginAttributesForNetworkState(
|
||||
return;
|
||||
}
|
||||
|
||||
aAttributes.SetPartitionKey(aFirstPartyURI);
|
||||
aAttributes.SetPartitionKey(aFirstPartyURI, false);
|
||||
}
|
||||
|
||||
enum SupportedScheme { HTTP, HTTPS };
|
||||
@@ -664,8 +667,9 @@ bool StoragePrincipalHelper::PartitionKeyHasBaseDomain(
|
||||
nsString scheme;
|
||||
nsString pkBaseDomain;
|
||||
int32_t port;
|
||||
bool success = OriginAttributes::ParsePartitionKey(aPartitionKey, scheme,
|
||||
pkBaseDomain, port);
|
||||
bool foreign;
|
||||
bool success = OriginAttributes::ParsePartitionKey(
|
||||
aPartitionKey, scheme, pkBaseDomain, port, foreign);
|
||||
|
||||
if (!success) {
|
||||
return false;
|
||||
@@ -674,4 +678,26 @@ bool StoragePrincipalHelper::PartitionKeyHasBaseDomain(
|
||||
return aBaseDomain.Equals(pkBaseDomain);
|
||||
}
|
||||
|
||||
// static
|
||||
void StoragePrincipalHelper::UpdatePartitionKeyWithForeignAncestorBit(
|
||||
nsAString& aKey, bool aForeignByAncestorContext) {
|
||||
bool site = 0 == aKey.Find(u"(");
|
||||
if (!site) {
|
||||
return;
|
||||
}
|
||||
if (aForeignByAncestorContext) {
|
||||
int32_t index = aKey.Find(u",f)");
|
||||
if (index == -1) {
|
||||
uint32_t cutStart = aKey.Length() - 1;
|
||||
aKey.ReplaceLiteral(cutStart, 1, u",f)");
|
||||
}
|
||||
} else {
|
||||
int32_t index = aKey.Find(u",f)");
|
||||
if (index != -1) {
|
||||
uint32_t cutLength = aKey.Length() - index;
|
||||
aKey.ReplaceLiteral(index, cutLength, u")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -351,6 +351,14 @@ class StoragePrincipalHelper final {
|
||||
|
||||
static bool PartitionKeyHasBaseDomain(const nsAString& aPartitionKey,
|
||||
const nsAString& aBaseDomain);
|
||||
|
||||
// Partition keys can have the same-site bit added or removed from them.
|
||||
// "(https,foo.com)", false -> "(https,foo.com)"
|
||||
// "(https,foo.com,f)", false -> "(https,foo.com)"
|
||||
// "(https,foo.com,f)", true -> "(https,foo.com,f)"
|
||||
// "(https,foo.com)", true -> "(https,foo.com,f)"
|
||||
static void UpdatePartitionKeyWithForeignAncestorBit(
|
||||
nsAString& aKey, bool aForeignByAncestorContext);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -1267,7 +1267,11 @@ Maybe<nsTArray<uint8_t>> nsRFPService::GenerateKey(nsIChannel* aChannel) {
|
||||
|
||||
// Set the partitionKey using the top level URI to ensure that the key is
|
||||
// specific to the top level site.
|
||||
attrs.SetPartitionKey(topLevelURI);
|
||||
bool foreignByAncestorContext =
|
||||
false; // Bug 1876575 will change this to
|
||||
// loadInfo->GetIsInThirdPartyContext() &&
|
||||
// !loadInfo->GetIsThirdPartyContextToTopWindow();
|
||||
attrs.SetPartitionKey(topLevelURI, foreignByAncestorContext);
|
||||
|
||||
nsAutoCString oaSuffix;
|
||||
attrs.CreateSuffix(oaSuffix);
|
||||
@@ -1337,8 +1341,14 @@ nsRFPService::CleanRandomKeyByPrincipal(nsIPrincipal* aPrincipal) {
|
||||
|
||||
OriginAttributes attrs = aPrincipal->OriginAttributesRef();
|
||||
nsCOMPtr<nsIURI> uri = aPrincipal->GetURI();
|
||||
attrs.SetPartitionKey(uri);
|
||||
|
||||
attrs.SetPartitionKey(uri, false);
|
||||
ClearBrowsingSessionKey(attrs);
|
||||
|
||||
// We must also include the cross-site embeds of this principal that end up
|
||||
// re-embedded back into the same principal's top level, otherwise state will
|
||||
// persist for this target
|
||||
attrs.SetPartitionKey(uri, true);
|
||||
ClearBrowsingSessionKey(attrs);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1354,14 +1364,21 @@ nsRFPService::CleanRandomKeyByDomain(const nsACString& aDomain) {
|
||||
|
||||
// Use the originAttributes to get the partitionKey.
|
||||
OriginAttributes attrs;
|
||||
attrs.SetPartitionKey(httpURI);
|
||||
attrs.SetPartitionKey(httpURI, false);
|
||||
|
||||
// Create a originAttributesPattern and set the http partitionKey to the
|
||||
// pattern.
|
||||
OriginAttributesPattern pattern;
|
||||
pattern.mPartitionKey.Reset();
|
||||
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
|
||||
ClearBrowsingSessionKey(pattern);
|
||||
|
||||
// We must also include the cross-site embeds of this principal that end up
|
||||
// re-embedded back into the same principal's top level, otherwise state will
|
||||
// persist for this target
|
||||
attrs.SetPartitionKey(httpURI, true);
|
||||
pattern.mPartitionKey.Reset();
|
||||
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
|
||||
ClearBrowsingSessionKey(pattern);
|
||||
|
||||
// Get https URI from the domain.
|
||||
@@ -1370,10 +1387,17 @@ nsRFPService::CleanRandomKeyByDomain(const nsACString& aDomain) {
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Use the originAttributes to get the partitionKey and set to the pattern.
|
||||
attrs.SetPartitionKey(httpsURI);
|
||||
attrs.SetPartitionKey(httpsURI, false);
|
||||
pattern.mPartitionKey.Reset();
|
||||
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
|
||||
ClearBrowsingSessionKey(pattern);
|
||||
|
||||
// We must also include the cross-site embeds of this principal that end up
|
||||
// re-embedded back into the same principal's top level, otherwise state will
|
||||
// persist for this target
|
||||
attrs.SetPartitionKey(httpsURI, true);
|
||||
pattern.mPartitionKey.Reset();
|
||||
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
|
||||
ClearBrowsingSessionKey(pattern);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1395,7 +1419,7 @@ nsRFPService::CleanRandomKeyByHost(const nsACString& aHost,
|
||||
|
||||
// Use the originAttributes to get the partitionKey.
|
||||
OriginAttributes attrs;
|
||||
attrs.SetPartitionKey(httpURI);
|
||||
attrs.SetPartitionKey(httpURI, false);
|
||||
|
||||
// Set the partitionKey to the pattern.
|
||||
pattern.mPartitionKey.Reset();
|
||||
@@ -1403,16 +1427,31 @@ nsRFPService::CleanRandomKeyByHost(const nsACString& aHost,
|
||||
|
||||
ClearBrowsingSessionKey(pattern);
|
||||
|
||||
// We must also include the cross-site embeds of this principal that end up
|
||||
// re-embedded back into the same principal's top level, otherwise state will
|
||||
// persist for this target
|
||||
attrs.SetPartitionKey(httpURI, true);
|
||||
pattern.mPartitionKey.Reset();
|
||||
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
|
||||
ClearBrowsingSessionKey(pattern);
|
||||
|
||||
// Get https URI from the host.
|
||||
nsCOMPtr<nsIURI> httpsURI;
|
||||
rv = NS_NewURI(getter_AddRefs(httpsURI), "https://"_ns + aHost);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Use the originAttributes to get the partitionKey and set to the pattern.
|
||||
attrs.SetPartitionKey(httpsURI);
|
||||
attrs.SetPartitionKey(httpsURI, false);
|
||||
pattern.mPartitionKey.Reset();
|
||||
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
|
||||
ClearBrowsingSessionKey(pattern);
|
||||
|
||||
// We must also include the cross-site embeds of this principal that end up
|
||||
// re-embedded back into the same principal's top level, otherwise state will
|
||||
// persist for this target
|
||||
attrs.SetPartitionKey(httpsURI, true);
|
||||
pattern.mPartitionKey.Reset();
|
||||
pattern.mPartitionKey.Construct(attrs.mPartitionKey);
|
||||
ClearBrowsingSessionKey(pattern);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -2054,8 +2093,9 @@ Maybe<RFPTarget> nsRFPService::GetOverriddenFingerprintingSettingsForChannel(
|
||||
nsAutoString scheme;
|
||||
nsAutoString domain;
|
||||
int32_t unused;
|
||||
bool unused2;
|
||||
if (!OriginAttributes::ParsePartitionKey(partitionKey, scheme, domain,
|
||||
unused)) {
|
||||
unused, unused2)) {
|
||||
MOZ_ASSERT(false);
|
||||
return Nothing();
|
||||
}
|
||||
@@ -2096,12 +2136,16 @@ Maybe<RFPTarget> nsRFPService::GetOverriddenFingerprintingSettingsForChannel(
|
||||
cookieJarSettings->GetPartitionKey(partitionKey);
|
||||
|
||||
OriginAttributes attrs;
|
||||
attrs.SetPartitionKey(topURI);
|
||||
attrs.SetPartitionKey(topURI, false);
|
||||
|
||||
OriginAttributes attrsForeignByAncestor;
|
||||
attrsForeignByAncestor.SetPartitionKey(topURI, true);
|
||||
|
||||
// The partitionKey of the channel could haven't been set here if the loading
|
||||
// channel is top-level.
|
||||
MOZ_ASSERT_IF(!partitionKey.IsEmpty(),
|
||||
attrs.mPartitionKey.Equals(partitionKey));
|
||||
attrs.mPartitionKey.Equals(partitionKey) ||
|
||||
attrsForeignByAncestor.mPartitionKey.Equals(partitionKey));
|
||||
#endif
|
||||
|
||||
return GetOverriddenFingerprintingSettingsForURI(topURI, uri);
|
||||
|
||||
Reference in New Issue
Block a user