Bug 1268726 - isolate shared worker by first party domain. r=baku

Tor 15564: Isolate SharedWorker by first party domain
uplift/refactor by Dave Huseby <dhuseby@mozilla.com>

review tweaks
This commit is contained in:
Arthur Edelstein 2016-09-19 21:13:00 -04:00
Родитель 7784aa2e51
Коммит dfebfaa34a
11 изменённых файлов: 96 добавлений и 37 удалений

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

@ -3097,6 +3097,48 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext,
return NS_FAILED(rv) ? false : NS_CP_ACCEPTED(decision);
}
// static
mozilla::PrincipalOriginAttributes
nsContentUtils::GetOriginAttributes(nsIDocument* aDocument)
{
if (!aDocument) {
return mozilla::PrincipalOriginAttributes();
}
nsCOMPtr<nsILoadGroup> loadGroup = aDocument->GetDocumentLoadGroup();
if (loadGroup) {
return GetOriginAttributes(loadGroup);
}
mozilla::PrincipalOriginAttributes attrs;
mozilla::NeckoOriginAttributes nattrs;
nsCOMPtr<nsIChannel> channel = aDocument->GetChannel();
if (channel && NS_GetOriginAttributes(channel, nattrs)) {
attrs.InheritFromNecko(nattrs);
}
return attrs;
}
// static
mozilla::PrincipalOriginAttributes
nsContentUtils::GetOriginAttributes(nsILoadGroup* aLoadGroup)
{
if (!aLoadGroup) {
return mozilla::PrincipalOriginAttributes();
}
mozilla::PrincipalOriginAttributes attrs;
mozilla::DocShellOriginAttributes dsattrs;
nsCOMPtr<nsIInterfaceRequestor> callbacks;
aLoadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (callbacks) {
nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(callbacks);
if (loadContext && loadContext->GetOriginAttributes(dsattrs)) {
attrs.InheritFromDocShellToDoc(dsattrs, nullptr);
}
}
return attrs;
}
// static
bool
nsContentUtils::IsInPrivateBrowsing(nsIDocument* aDoc)

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

@ -785,6 +785,18 @@ public:
bool aIsForWindow,
uint32_t *aArgCount, const char*** aArgNames);
/**
* Returns origin attributes of the document.
**/
static mozilla::PrincipalOriginAttributes
GetOriginAttributes(nsIDocument* aDoc);
/**
* Returns origin attributes of the load group.
**/
static mozilla::PrincipalOriginAttributes
GetOriginAttributes(nsILoadGroup* aLoadGroup);
/**
* Returns true if this document is in a Private Browsing window.
*/

2
dom/cache/CacheStorage.cpp поставляемый
Просмотреть файл

@ -196,7 +196,7 @@ CacheStorage::CreateOnWorker(Namespace aNamespace, nsIGlobalObject* aGlobal,
return ref.forget();
}
if (aWorkerPrivate->IsInPrivateBrowsing()) {
if (aWorkerPrivate->GetOriginAttributes().mPrivateBrowsingId > 0) {
NS_WARNING("CacheStorage not supported during private browsing.");
RefPtr<CacheStorage> ref = new CacheStorage(NS_ERROR_DOM_SECURITY_ERR);
return ref.forget();

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

@ -245,29 +245,24 @@ GetWorkerPref(const nsACString& aPref,
return result;
}
// This function creates a key for a SharedWorker composed by "name|scriptSpec".
// If the name contains a '|', this will be replaced by '||'.
// This fn creates a key for a SharedWorker that contains the name, script
// spec, and the serialized origin attributes:
// "name|scriptSpec^key1=val1&key2=val2&key3=val3"
void
GenerateSharedWorkerKey(const nsACString& aScriptSpec, const nsACString& aName,
bool aPrivateBrowsing, nsCString& aKey)
GenerateSharedWorkerKey(const nsACString& aScriptSpec,
const nsACString& aName,
const PrincipalOriginAttributes& aAttrs,
nsCString& aKey)
{
nsAutoCString suffix;
aAttrs.CreateSuffix(suffix);
aKey.Truncate();
aKey.SetCapacity(aScriptSpec.Length() + aName.Length() + 3);
aKey.Append(aPrivateBrowsing ? "1|" : "0|");
nsACString::const_iterator start, end;
aName.BeginReading(start);
aName.EndReading(end);
for (; start != end; ++start) {
if (*start == '|') {
aKey.AppendASCII("||");
} else {
aKey.Append(*start);
}
}
aKey.SetCapacity(aName.Length() + aScriptSpec.Length() + suffix.Length() + 2);
aKey.Append(aName);
aKey.Append('|');
aKey.Append(aScriptSpec);
aKey.Append(suffix);
}
void
@ -1641,7 +1636,7 @@ RuntimeService::RegisterWorker(WorkerPrivate* aWorkerPrivate)
const nsCString& sharedWorkerName = aWorkerPrivate->WorkerName();
nsAutoCString key;
GenerateSharedWorkerKey(sharedWorkerScriptSpec, sharedWorkerName,
aWorkerPrivate->IsInPrivateBrowsing(), key);
aWorkerPrivate->GetOriginAttributes(), key);
MOZ_ASSERT(!domainInfo->mSharedWorkerInfos.Get(key));
SharedWorkerInfo* sharedWorkerInfo =
@ -1718,7 +1713,7 @@ RuntimeService::RemoveSharedWorker(WorkerDomainInfo* aDomainInfo,
#ifdef DEBUG
nsAutoCString key;
GenerateSharedWorkerKey(data->mScriptSpec, data->mName,
aWorkerPrivate->IsInPrivateBrowsing(), key);
aWorkerPrivate->GetOriginAttributes(), key);
MOZ_ASSERT(iter.Key() == key);
#endif
iter.Remove();
@ -2434,9 +2429,10 @@ RuntimeService::CreateSharedWorkerFromLoadInfo(JSContext* aCx,
nsresult rv = aLoadInfo->mResolvedScriptURI->GetSpec(scriptSpec);
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(aLoadInfo->mPrincipal);
nsAutoCString key;
GenerateSharedWorkerKey(scriptSpec, aName,
aLoadInfo->mPrivateBrowsing, key);
BasePrincipal::Cast(aLoadInfo->mPrincipal)->OriginAttributesRef(), key);
if (mDomainMap.Get(aLoadInfo->mDomain, &domainInfo) &&
domainInfo->mSharedWorkerInfos.Get(key, &sharedWorkerInfo)) {

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

@ -350,7 +350,7 @@ public:
explicit CacheCreator(WorkerPrivate* aWorkerPrivate)
: mCacheName(aWorkerPrivate->ServiceWorkerCacheName())
, mPrivateBrowsing(aWorkerPrivate->IsInPrivateBrowsing())
, mOriginAttributes(aWorkerPrivate->GetOriginAttributes())
{
MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
MOZ_ASSERT(aWorkerPrivate->LoadScriptAsPartOfLoadingServiceWorkerScript());
@ -411,7 +411,7 @@ private:
nsTArray<RefPtr<CacheScriptLoader>> mLoaders;
nsString mCacheName;
bool mPrivateBrowsing;
PrincipalOriginAttributes mOriginAttributes;
};
NS_IMPL_ISUPPORTS0(CacheCreator)
@ -1467,7 +1467,7 @@ CacheCreator::CreateCacheStorage(nsIPrincipal* aPrincipal)
// If we're in private browsing mode, don't even try to create the
// CacheStorage. Instead, just fail immediately to terminate the
// ServiceWorker load.
if (NS_WARN_IF(mPrivateBrowsing)) {
if (NS_WARN_IF(mOriginAttributes.mPrivateBrowsingId > 0)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
@ -1478,7 +1478,8 @@ CacheCreator::CreateCacheStorage(nsIPrincipal* aPrincipal)
mCacheStorage =
CacheStorage::CreateOnMainThread(mozilla::dom::cache::CHROME_ONLY_NAMESPACE,
mSandboxGlobalObject,
aPrincipal, mPrivateBrowsing,
aPrincipal,
false, /* privateBrowsing can't be true here */
true /* force trusted origin */,
error);
if (NS_WARN_IF(error.Failed())) {

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

@ -160,6 +160,8 @@ ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
, mSkipWaitingFlag(false)
{
MOZ_ASSERT(mPrincipal);
// cache origin attributes so we can use them off main thread
mOriginAttributes = BasePrincipal::Cast(mPrincipal)->OriginAttributesRef();
MOZ_ASSERT(!mScope.IsEmpty());
MOZ_ASSERT(!mScriptSpec.IsEmpty());
MOZ_ASSERT(!mCacheName.IsEmpty());

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

@ -31,6 +31,7 @@ private:
const nsCString mScriptSpec;
const nsString mCacheName;
ServiceWorkerState mState;
PrincipalOriginAttributes mOriginAttributes;
// This id is shared with WorkerPrivate to match requests issued by service
// workers to their corresponding serviceWorkerInfo.
@ -104,6 +105,12 @@ public:
return mState;
}
const PrincipalOriginAttributes&
GetOriginAttributes() const
{
return mOriginAttributes;
}
const nsString&
CacheName() const
{

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

@ -1714,7 +1714,7 @@ ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
nsContentUtils::StorageAccess access =
nsContentUtils::StorageAllowedForPrincipal(info.mPrincipal);
info.mStorageAllowed = access > nsContentUtils::StorageAccess::ePrivateBrowsing;
info.mPrivateBrowsing = false;
info.mOriginAttributes = mInfo->GetOriginAttributes();
nsCOMPtr<nsIContentSecurityPolicy> csp;
rv = info.mPrincipal->GetCsp(getter_AddRefs(csp));

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

@ -1739,7 +1739,6 @@ WorkerLoadInfo::WorkerLoadInfo()
, mXHRParamsAllowed(false)
, mPrincipalIsSystem(false)
, mStorageAllowed(false)
, mPrivateBrowsing(true)
, mServiceWorkersTestingInWindow(false)
{
MOZ_COUNT_CTOR(WorkerLoadInfo);
@ -1797,8 +1796,8 @@ WorkerLoadInfo::StealFrom(WorkerLoadInfo& aOther)
mXHRParamsAllowed = aOther.mXHRParamsAllowed;
mPrincipalIsSystem = aOther.mPrincipalIsSystem;
mStorageAllowed = aOther.mStorageAllowed;
mPrivateBrowsing = aOther.mPrivateBrowsing;
mServiceWorkersTestingInWindow = aOther.mServiceWorkersTestingInWindow;
mOriginAttributes = aOther.mOriginAttributes;
}
template <class Derived>
@ -3426,7 +3425,7 @@ WorkerPrivateParent<Derived>::SetPrincipal(nsIPrincipal* aPrincipal,
mLoadInfo.mLoadGroup = aLoadGroup;
mLoadInfo.mPrincipalInfo = new PrincipalInfo();
mLoadInfo.mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(aLoadGroup);
mLoadInfo.mOriginAttributes = nsContentUtils::GetOriginAttributes(aLoadGroup);
MOZ_ALWAYS_SUCCEEDS(
PrincipalToPrincipalInfo(aPrincipal, mLoadInfo.mPrincipalInfo));
@ -4193,7 +4192,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
loadInfo.mFromWindow = aParent->IsFromWindow();
loadInfo.mWindowID = aParent->WindowID();
loadInfo.mStorageAllowed = aParent->IsStorageAllowed();
loadInfo.mPrivateBrowsing = aParent->IsInPrivateBrowsing();
loadInfo.mOriginAttributes = aParent->GetOriginAttributes();
loadInfo.mServiceWorkersTestingInWindow =
aParent->ServiceWorkersTestingInWindow();
} else {
@ -4317,7 +4316,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
nsContentUtils::StorageAccess access =
nsContentUtils::StorageAllowedForWindow(globalWindow);
loadInfo.mStorageAllowed = access > nsContentUtils::StorageAccess::eDeny;
loadInfo.mPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(document);
loadInfo.mOriginAttributes = nsContentUtils::GetOriginAttributes(document);
} else {
// Not a window
MOZ_ASSERT(isChrome);
@ -4359,7 +4358,7 @@ WorkerPrivate::GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
loadInfo.mFromWindow = false;
loadInfo.mWindowID = UINT64_MAX;
loadInfo.mStorageAllowed = true;
loadInfo.mPrivateBrowsing = false;
loadInfo.mOriginAttributes = PrincipalOriginAttributes();
}
MOZ_ASSERT(loadInfo.mPrincipal);

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

@ -783,10 +783,10 @@ public:
return mLoadInfo.mStorageAllowed;
}
bool
IsInPrivateBrowsing() const
const PrincipalOriginAttributes&
GetOriginAttributes() const
{
return mLoadInfo.mPrivateBrowsing;
return mLoadInfo.mOriginAttributes;
}
// Determine if the SW testing per-window flag is set by devtools

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

@ -269,8 +269,8 @@ struct WorkerLoadInfo
bool mXHRParamsAllowed;
bool mPrincipalIsSystem;
bool mStorageAllowed;
bool mPrivateBrowsing;
bool mServiceWorkersTestingInWindow;
PrincipalOriginAttributes mOriginAttributes;
WorkerLoadInfo();
~WorkerLoadInfo();