Bug 1731990 - Part 3: Use the partitionKey from the foreign partitioned principal in ServiceWorkerPrivate. r=pbz,dom-storage-reviewers,edenchuang

We used to use the principal URL for the partitionKey in
ServiceWorkerPrivateImpl. This is correct if the ServiceWorker only
works in first-party context. But, it isn't correct in third-party
context.

To fix that, we can directly use the foreign paritioned principal from
the ServiceWorkerPrivate to get the partitionKey in third-party context.
For the first-party context, we can still use the original approach to
get the partitionKey.

Differential Revision: https://phabricator.services.mozilla.com/D128733
This commit is contained in:
Tim Huang 2021-11-25 13:11:35 +00:00
Родитель bdeaf4cf23
Коммит 7ff4cf104f
3 изменённых файлов: 36 добавлений и 6 удалений

Просмотреть файл

@ -49,6 +49,7 @@
#include "mozilla/net/CookieJarSettings.h"
#include "mozilla/net/NeckoChannelParams.h"
#include "mozilla/Services.h"
#include "mozilla/StoragePrincipalHelper.h"
#include "mozilla/Telemetry.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/StaticPrefs_dom.h"
@ -1671,16 +1672,31 @@ nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
info.mPrincipal = mInfo->Principal();
info.mLoadingPrincipal = info.mPrincipal;
// PartitionedPrincipal for ServiceWorkers is equal to mPrincipal because, at
// the moment, ServiceWorkers are not exposed in partitioned contexts.
info.mPartitionedPrincipal = info.mPrincipal;
info.mCookieJarSettings =
mozilla::net::CookieJarSettings::Create(info.mPrincipal);
MOZ_ASSERT(info.mCookieJarSettings);
net::CookieJarSettings::Cast(info.mCookieJarSettings)
->SetPartitionKey(info.mResolvedScriptURI);
// We can get the partitionKey from the principal of the ServiceWorker because
// it's a foreign partitioned principal. In other words, the principal will
// have the partitionKey if it's in a third-party context. Otherwise, we can
// set the partitionKey via the script URI because it's in the first-party
// context.
if (!info.mPrincipal->OriginAttributesRef().mPartitionKey.IsEmpty()) {
net::CookieJarSettings::Cast(info.mCookieJarSettings)
->SetPartitionKey(info.mPrincipal->OriginAttributesRef().mPartitionKey);
} else {
net::CookieJarSettings::Cast(info.mCookieJarSettings)
->SetPartitionKey(info.mResolvedScriptURI);
}
nsCOMPtr<nsIPrincipal> partitionedPrincipal;
StoragePrincipalHelper::CreatePartitionedPrincipalForServiceWorker(
info.mPrincipal, info.mCookieJarSettings,
getter_AddRefs(partitionedPrincipal));
info.mPartitionedPrincipal = partitionedPrincipal;
info.mStorageAccess =
StorageAllowedForServiceWorker(info.mPrincipal, info.mCookieJarSettings);

Просмотреть файл

@ -160,7 +160,18 @@ nsresult ServiceWorkerPrivateImpl::Initialize() {
net::CookieJarSettings::Create(principal);
MOZ_ASSERT(cookieJarSettings);
net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri);
// We can populate the partitionKey from the originAttribute of the principal
// if it has partitionKey set. It's because ServiceWorker is using the foreign
// partitioned principal and it implies that it's a third-party service
// worker. So, the cookieJarSettings can directly use the partitionKey from
// it. For first-party case, we can populate the partitionKey from the
// principal URI.
if (!principal->OriginAttributesRef().mPartitionKey.IsEmpty()) {
net::CookieJarSettings::Cast(cookieJarSettings)
->SetPartitionKey(principal->OriginAttributesRef().mPartitionKey);
} else {
net::CookieJarSettings::Cast(cookieJarSettings)->SetPartitionKey(uri);
}
net::CookieJarSettingsArgs cjsData;
net::CookieJarSettings::Cast(cookieJarSettings)->Serialize(cjsData);

Просмотреть файл

@ -157,6 +157,9 @@ class CookieJarSettings final : public nsICookieJarSettings {
void UpdateIsOnContentBlockingAllowList(nsIChannel* aChannel);
void SetPartitionKey(nsIURI* aURI);
void SetPartitionKey(const nsAString& aPartitionKey) {
mPartitionKey = aPartitionKey;
}
const nsAString& GetPartitionKey() { return mPartitionKey; };
// Utility function to test if the passed cookiebahvior is