From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- caps/BasePrincipal.cpp | 777 +++++++++ caps/BasePrincipal.h | 342 ++++ caps/DomainPolicy.cpp | 260 +++ caps/DomainPolicy.h | 72 + caps/moz.build | 63 + caps/nsIAddonPolicyService.idl | 78 + caps/nsIDomainPolicy.idl | 80 + caps/nsIPrincipal.idl | 367 ++++ caps/nsIScriptSecurityManager.idl | 305 ++++ caps/nsJSPrincipals.cpp | 299 ++++ caps/nsJSPrincipals.h | 66 + caps/nsNullPrincipal.cpp | 193 +++ caps/nsNullPrincipal.h | 78 + caps/nsNullPrincipalURI.cpp | 362 ++++ caps/nsNullPrincipalURI.h | 59 + caps/nsPrincipal.cpp | 854 ++++++++++ caps/nsPrincipal.h | 110 ++ caps/nsScriptSecurityManager.cpp | 1759 ++++++++++++++++++++ caps/nsScriptSecurityManager.h | 162 ++ caps/nsSystemPrincipal.cpp | 141 ++ caps/nsSystemPrincipal.h | 60 + caps/tests/gtest/TestOriginAttributes.cpp | 38 + caps/tests/gtest/moz.build | 13 + caps/tests/mochitest/browser.ini | 1 + caps/tests/mochitest/browser_checkloaduri.js | 292 ++++ caps/tests/mochitest/chrome.ini | 9 + caps/tests/mochitest/file_data.txt | 1 + caps/tests/mochitest/file_disableScript.html | 11 + caps/tests/mochitest/mochitest.ini | 13 + caps/tests/mochitest/resource_test_file.html | 2 + caps/tests/mochitest/test_addonMayLoad.html | 97 ++ .../mochitest/test_app_principal_equality.html | 88 + caps/tests/mochitest/test_bug246699.html | 65 + caps/tests/mochitest/test_bug292789.html | 105 ++ caps/tests/mochitest/test_bug423375.html | 44 + caps/tests/mochitest/test_bug470804.html | 41 + caps/tests/mochitest/test_bug995943.xul | 115 ++ caps/tests/mochitest/test_disableScript.xul | 339 ++++ .../mochitest/test_disallowInheritPrincipal.html | 60 + caps/tests/mochitest/test_extensionURL.html | 166 ++ caps/tests/unit/test_origin.js | 307 ++++ caps/tests/unit/xpcshell.ini | 5 + 42 files changed, 8299 insertions(+) create mode 100644 caps/BasePrincipal.cpp create mode 100644 caps/BasePrincipal.h create mode 100644 caps/DomainPolicy.cpp create mode 100644 caps/DomainPolicy.h create mode 100644 caps/moz.build create mode 100644 caps/nsIAddonPolicyService.idl create mode 100644 caps/nsIDomainPolicy.idl create mode 100644 caps/nsIPrincipal.idl create mode 100644 caps/nsIScriptSecurityManager.idl create mode 100644 caps/nsJSPrincipals.cpp create mode 100644 caps/nsJSPrincipals.h create mode 100644 caps/nsNullPrincipal.cpp create mode 100644 caps/nsNullPrincipal.h create mode 100644 caps/nsNullPrincipalURI.cpp create mode 100644 caps/nsNullPrincipalURI.h create mode 100644 caps/nsPrincipal.cpp create mode 100644 caps/nsPrincipal.h create mode 100644 caps/nsScriptSecurityManager.cpp create mode 100644 caps/nsScriptSecurityManager.h create mode 100644 caps/nsSystemPrincipal.cpp create mode 100644 caps/nsSystemPrincipal.h create mode 100644 caps/tests/gtest/TestOriginAttributes.cpp create mode 100644 caps/tests/gtest/moz.build create mode 100644 caps/tests/mochitest/browser.ini create mode 100644 caps/tests/mochitest/browser_checkloaduri.js create mode 100644 caps/tests/mochitest/chrome.ini create mode 100644 caps/tests/mochitest/file_data.txt create mode 100644 caps/tests/mochitest/file_disableScript.html create mode 100644 caps/tests/mochitest/mochitest.ini create mode 100644 caps/tests/mochitest/resource_test_file.html create mode 100644 caps/tests/mochitest/test_addonMayLoad.html create mode 100644 caps/tests/mochitest/test_app_principal_equality.html create mode 100644 caps/tests/mochitest/test_bug246699.html create mode 100644 caps/tests/mochitest/test_bug292789.html create mode 100644 caps/tests/mochitest/test_bug423375.html create mode 100644 caps/tests/mochitest/test_bug470804.html create mode 100644 caps/tests/mochitest/test_bug995943.xul create mode 100644 caps/tests/mochitest/test_disableScript.xul create mode 100644 caps/tests/mochitest/test_disallowInheritPrincipal.html create mode 100644 caps/tests/mochitest/test_extensionURL.html create mode 100644 caps/tests/unit/test_origin.js create mode 100644 caps/tests/unit/xpcshell.ini (limited to 'caps') diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp new file mode 100644 index 000000000..b768d5c1f --- /dev/null +++ b/caps/BasePrincipal.cpp @@ -0,0 +1,777 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/BasePrincipal.h" + +#include "nsDocShell.h" +#ifdef MOZ_CRASHREPORTER +#include "nsExceptionHandler.h" +#endif +#include "nsIAddonPolicyService.h" +#include "nsIContentSecurityPolicy.h" +#include "nsIEffectiveTLDService.h" +#include "nsIObjectInputStream.h" +#include "nsIObjectOutputStream.h" + +#include "nsPrincipal.h" +#include "nsNetUtil.h" +#include "nsIURIWithPrincipal.h" +#include "nsNullPrincipal.h" +#include "nsScriptSecurityManager.h" +#include "nsServiceManagerUtils.h" + +#include "mozilla/dom/ChromeUtils.h" +#include "mozilla/dom/CSPDictionariesBinding.h" +#include "mozilla/dom/quota/QuotaManager.h" +#include "mozilla/dom/ToJSValue.h" +#include "mozilla/dom/URLSearchParams.h" + +namespace mozilla { + +using dom::URLParams; + +void +PrincipalOriginAttributes::InheritFromDocShellToDoc(const DocShellOriginAttributes& aAttrs, + const nsIURI* aURI) +{ + mAppId = aAttrs.mAppId; + mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser; + + // addonId is computed from the principal URI and never propagated + mUserContextId = aAttrs.mUserContextId; + + mPrivateBrowsingId = aAttrs.mPrivateBrowsingId; + mFirstPartyDomain = aAttrs.mFirstPartyDomain; +} + +void +PrincipalOriginAttributes::InheritFromNecko(const NeckoOriginAttributes& aAttrs) +{ + mAppId = aAttrs.mAppId; + mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser; + + // addonId is computed from the principal URI and never propagated + mUserContextId = aAttrs.mUserContextId; + + mPrivateBrowsingId = aAttrs.mPrivateBrowsingId; + mFirstPartyDomain = aAttrs.mFirstPartyDomain; +} + +void +PrincipalOriginAttributes::StripUserContextIdAndFirstPartyDomain() +{ + mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID; + mFirstPartyDomain.Truncate(); +} + +void +DocShellOriginAttributes::InheritFromDocToChildDocShell(const PrincipalOriginAttributes& aAttrs) +{ + mAppId = aAttrs.mAppId; + mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser; + + // addonId is computed from the principal URI and never propagated + mUserContextId = aAttrs.mUserContextId; + + mPrivateBrowsingId = aAttrs.mPrivateBrowsingId; + mFirstPartyDomain = aAttrs.mFirstPartyDomain; +} + +void +NeckoOriginAttributes::InheritFromDocToNecko(const PrincipalOriginAttributes& aAttrs) +{ + mAppId = aAttrs.mAppId; + mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser; + + // addonId is computed from the principal URI and never propagated + mUserContextId = aAttrs.mUserContextId; + + mPrivateBrowsingId = aAttrs.mPrivateBrowsingId; + mFirstPartyDomain = aAttrs.mFirstPartyDomain; +} + +void +NeckoOriginAttributes::InheritFromDocShellToNecko(const DocShellOriginAttributes& aAttrs, + const bool aIsTopLevelDocument, + nsIURI* aURI) +{ + mAppId = aAttrs.mAppId; + mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser; + + // addonId is computed from the principal URI and never propagated + mUserContextId = aAttrs.mUserContextId; + + mPrivateBrowsingId = aAttrs.mPrivateBrowsingId; + + bool isFirstPartyEnabled = IsFirstPartyEnabled(); + + // When the pref is on, we also compute the firstPartyDomain attribute + // if this is for top-level document. + if (isFirstPartyEnabled && aIsTopLevelDocument) { + nsCOMPtr tldService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID); + MOZ_ASSERT(tldService); + if (!tldService) { + return; + } + + nsAutoCString baseDomain; + tldService->GetBaseDomain(aURI, 0, baseDomain); + mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain); + } else { + mFirstPartyDomain = aAttrs.mFirstPartyDomain; + } +} + +void +OriginAttributes::CreateSuffix(nsACString& aStr) const +{ + UniquePtr params(new URLParams()); + nsAutoString value; + + // + // Important: While serializing any string-valued attributes, perform a + // release-mode assertion to make sure that they don't contain characters that + // will break the quota manager when it uses the serialization for file + // naming (see addonId below). + // + + if (mAppId != nsIScriptSecurityManager::NO_APP_ID) { + value.AppendInt(mAppId); + params->Set(NS_LITERAL_STRING("appId"), value); + } + + if (mInIsolatedMozBrowser) { + params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1")); + } + + if (!mAddonId.IsEmpty()) { + if (mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) != kNotFound) { +#ifdef MOZ_CRASHREPORTER + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Crash_AddonId"), + NS_ConvertUTF16toUTF8(mAddonId)); +#endif + MOZ_CRASH(); + } + params->Set(NS_LITERAL_STRING("addonId"), mAddonId); + } + + if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) { + value.Truncate(); + value.AppendInt(mUserContextId); + params->Set(NS_LITERAL_STRING("userContextId"), value); + } + + + if (mPrivateBrowsingId) { + value.Truncate(); + value.AppendInt(mPrivateBrowsingId); + params->Set(NS_LITERAL_STRING("privateBrowsingId"), value); + } + + if (!mFirstPartyDomain.IsEmpty()) { + MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound); + params->Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain); + } + + aStr.Truncate(); + + params->Serialize(value); + if (!value.IsEmpty()) { + aStr.AppendLiteral("^"); + aStr.Append(NS_ConvertUTF16toUTF8(value)); + } + +// In debug builds, check the whole string for illegal characters too (just in case). +#ifdef DEBUG + nsAutoCString str; + str.Assign(aStr); + MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound); +#endif +} + +void +OriginAttributes::CreateAnonymizedSuffix(nsACString& aStr) const +{ + OriginAttributes attrs = *this; + + if (!attrs.mFirstPartyDomain.IsEmpty()) { + attrs.mFirstPartyDomain.AssignLiteral("_anonymizedFirstPartyDomain_"); + } + + attrs.CreateSuffix(aStr); +} + +namespace { + +class MOZ_STACK_CLASS PopulateFromSuffixIterator final + : public URLParams::ForEachIterator +{ +public: + explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes) + : mOriginAttributes(aOriginAttributes) + { + MOZ_ASSERT(aOriginAttributes); + // If mPrivateBrowsingId is passed in as >0 and is not present in the suffix, + // then it will remain >0 when it should be 0 according to the suffix. Set to 0 before + // iterating to fix this. + mOriginAttributes->mPrivateBrowsingId = 0; + } + + bool URLParamsIterator(const nsString& aName, + const nsString& aValue) override + { + if (aName.EqualsLiteral("appId")) { + nsresult rv; + int64_t val = aValue.ToInteger64(&rv); + NS_ENSURE_SUCCESS(rv, false); + NS_ENSURE_TRUE(val <= UINT32_MAX, false); + mOriginAttributes->mAppId = static_cast(val); + + return true; + } + + if (aName.EqualsLiteral("inBrowser")) { + if (!aValue.EqualsLiteral("1")) { + return false; + } + + mOriginAttributes->mInIsolatedMozBrowser = true; + return true; + } + + if (aName.EqualsLiteral("addonId")) { + MOZ_RELEASE_ASSERT(mOriginAttributes->mAddonId.IsEmpty()); + mOriginAttributes->mAddonId.Assign(aValue); + return true; + } + + if (aName.EqualsLiteral("userContextId")) { + nsresult rv; + int64_t val = aValue.ToInteger64(&rv); + NS_ENSURE_SUCCESS(rv, false); + NS_ENSURE_TRUE(val <= UINT32_MAX, false); + mOriginAttributes->mUserContextId = static_cast(val); + + return true; + } + + if (aName.EqualsLiteral("privateBrowsingId")) { + nsresult rv; + int64_t val = aValue.ToInteger64(&rv); + NS_ENSURE_SUCCESS(rv, false); + NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false); + mOriginAttributes->mPrivateBrowsingId = static_cast(val); + + return true; + } + + if (aName.EqualsLiteral("firstPartyDomain")) { + MOZ_RELEASE_ASSERT(mOriginAttributes->mFirstPartyDomain.IsEmpty()); + mOriginAttributes->mFirstPartyDomain.Assign(aValue); + return true; + } + + // No other attributes are supported. + return false; + } + +private: + OriginAttributes* mOriginAttributes; +}; + +} // namespace + +bool +OriginAttributes::PopulateFromSuffix(const nsACString& aStr) +{ + if (aStr.IsEmpty()) { + return true; + } + + if (aStr[0] != '^') { + return false; + } + + UniquePtr params(new URLParams()); + params->ParseInput(Substring(aStr, 1, aStr.Length() - 1)); + + PopulateFromSuffixIterator iterator(this); + return params->ForEach(iterator); +} + +bool +OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin, + nsACString& aOriginNoSuffix) +{ + // RFindChar is only available on nsCString. + nsCString origin(aOrigin); + int32_t pos = origin.RFindChar('^'); + + if (pos == kNotFound) { + aOriginNoSuffix = origin; + return true; + } + + aOriginNoSuffix = Substring(origin, 0, pos); + return PopulateFromSuffix(Substring(origin, pos)); +} + +void +OriginAttributes::SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing) +{ + mPrivateBrowsingId = aInPrivateBrowsing ? 1 : 0; +} + +void +OriginAttributes::SetFromGenericAttributes(const GenericOriginAttributes& aAttrs) +{ + mAppId = aAttrs.mAppId; + mInIsolatedMozBrowser = aAttrs.mInIsolatedMozBrowser; + mAddonId = aAttrs.mAddonId; + mUserContextId = aAttrs.mUserContextId; + mPrivateBrowsingId = aAttrs.mPrivateBrowsingId; + mFirstPartyDomain = aAttrs.mFirstPartyDomain; +} + +/* static */ +bool +OriginAttributes::IsFirstPartyEnabled() +{ + // Cache the privacy.firstparty.isolate pref. + static bool sFirstPartyIsolation = false; + static bool sCachedFirstPartyPref = false; + if (!sCachedFirstPartyPref) { + sCachedFirstPartyPref = true; + Preferences::AddBoolVarCache(&sFirstPartyIsolation, "privacy.firstparty.isolate"); + } + + return sFirstPartyIsolation; +} + +BasePrincipal::BasePrincipal() +{} + +BasePrincipal::~BasePrincipal() +{} + +NS_IMETHODIMP +BasePrincipal::GetOrigin(nsACString& aOrigin) +{ + nsresult rv = GetOriginInternal(aOrigin); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoCString suffix; + mOriginAttributes.CreateSuffix(suffix); + aOrigin.Append(suffix); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetOriginNoSuffix(nsACString& aOrigin) +{ + return GetOriginInternal(aOrigin); +} + +bool +BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) +{ + MOZ_ASSERT(aOther); + + // Expanded principals handle origin attributes for each of their + // sub-principals individually, null principals do only simple checks for + // pointer equality, and system principals are immune to origin attributes + // checks, so only do this check for codebase principals. + if (Kind() == eCodebasePrincipal && + OriginAttributesRef() != Cast(aOther)->OriginAttributesRef()) { + return false; + } + + return SubsumesInternal(aOther, aConsideration); +} + +NS_IMETHODIMP +BasePrincipal::Equals(nsIPrincipal *aOther, bool *aResult) +{ + NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG); + *aResult = Subsumes(aOther, DontConsiderDocumentDomain) && + Cast(aOther)->Subsumes(this, DontConsiderDocumentDomain); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::EqualsConsideringDomain(nsIPrincipal *aOther, bool *aResult) +{ + NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG); + *aResult = Subsumes(aOther, ConsiderDocumentDomain) && + Cast(aOther)->Subsumes(this, ConsiderDocumentDomain); + return NS_OK; +} + +bool +BasePrincipal::EqualsIgnoringAddonId(nsIPrincipal *aOther) +{ + MOZ_ASSERT(aOther); + + // Note that this will not work for expanded principals, nor is it intended + // to. + if (!dom::ChromeUtils::IsOriginAttributesEqualIgnoringAddonId( + OriginAttributesRef(), Cast(aOther)->OriginAttributesRef())) { + return false; + } + + return SubsumesInternal(aOther, DontConsiderDocumentDomain) && + Cast(aOther)->SubsumesInternal(this, DontConsiderDocumentDomain); +} + +NS_IMETHODIMP +BasePrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult) +{ + NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG); + *aResult = Subsumes(aOther, DontConsiderDocumentDomain); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::SubsumesConsideringDomain(nsIPrincipal *aOther, bool *aResult) +{ + NS_ENSURE_TRUE(aOther, NS_ERROR_INVALID_ARG); + *aResult = Subsumes(aOther, ConsiderDocumentDomain); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal) +{ + // Check the internal method first, which allows us to quickly approve loads + // for the System Principal. + if (MayLoadInternal(aURI)) { + return NS_OK; + } + + nsresult rv; + if (aAllowIfInheritsPrincipal) { + // If the caller specified to allow loads of URIs that inherit + // our principal, allow the load if this URI inherits its principal. + bool doesInheritSecurityContext; + rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT, + &doesInheritSecurityContext); + if (NS_SUCCEEDED(rv) && doesInheritSecurityContext) { + return NS_OK; + } + } + + bool fetchableByAnyone; + rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE, &fetchableByAnyone); + if (NS_SUCCEEDED(rv) && fetchableByAnyone) { + return NS_OK; + } + + if (aReport) { + nsCOMPtr prinURI; + rv = GetURI(getter_AddRefs(prinURI)); + if (NS_SUCCEEDED(rv) && prinURI) { + nsScriptSecurityManager::ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"), prinURI, aURI); + } + } + + return NS_ERROR_DOM_BAD_URI; +} + +NS_IMETHODIMP +BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) +{ + NS_IF_ADDREF(*aCsp = mCSP); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) +{ + // Never destroy an existing CSP on the principal. + // This method should only be called in rare cases. + + MOZ_ASSERT(!mCSP, "do not destroy an existing CSP"); + if (mCSP) { + return NS_ERROR_ALREADY_INITIALIZED; + } + + mCSP = aCsp; + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::EnsureCSP(nsIDOMDocument* aDocument, + nsIContentSecurityPolicy** aCSP) +{ + if (mCSP) { + // if there is a CSP already associated with this principal + // then just return that - do not overwrite it!!! + NS_IF_ADDREF(*aCSP = mCSP); + return NS_OK; + } + + nsresult rv = NS_OK; + mCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // Store the request context for violation reports + rv = aDocument ? mCSP->SetRequestContext(aDocument, nullptr) + : mCSP->SetRequestContext(nullptr, this); + NS_ENSURE_SUCCESS(rv, rv); + NS_IF_ADDREF(*aCSP = mCSP); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) +{ + NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument, + nsIContentSecurityPolicy** aPreloadCSP) +{ + if (mPreloadCSP) { + // if there is a speculative CSP already associated with this principal + // then just return that - do not overwrite it!!! + NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP); + return NS_OK; + } + + nsresult rv = NS_OK; + mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // Store the request context for violation reports + rv = aDocument ? mPreloadCSP->SetRequestContext(aDocument, nullptr) + : mPreloadCSP->SetRequestContext(nullptr, this); + NS_ENSURE_SUCCESS(rv, rv); + NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetCspJSON(nsAString& outCSPinJSON) +{ + outCSPinJSON.Truncate(); + dom::CSPPolicies jsonPolicies; + + if (!mCSP) { + jsonPolicies.ToJSON(outCSPinJSON); + return NS_OK; + } + return mCSP->ToJSON(outCSPinJSON); +} + +NS_IMETHODIMP +BasePrincipal::GetIsNullPrincipal(bool* aResult) +{ + *aResult = Kind() == eNullPrincipal; + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetIsCodebasePrincipal(bool* aResult) +{ + *aResult = Kind() == eCodebasePrincipal; + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetIsExpandedPrincipal(bool* aResult) +{ + *aResult = Kind() == eExpandedPrincipal; + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetIsSystemPrincipal(bool* aResult) +{ + *aResult = Kind() == eSystemPrincipal; + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle aVal) +{ + if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes) +{ + mOriginAttributes.CreateSuffix(aOriginAttributes); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetAppStatus(uint16_t* aAppStatus) +{ + if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) { + NS_WARNING("Asking for app status on a principal with an unknown app id"); + *aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED; + return NS_OK; + } + + *aAppStatus = nsScriptSecurityManager::AppStatusForPrincipal(this); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetAppId(uint32_t* aAppId) +{ + if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) { + MOZ_ASSERT(false); + *aAppId = nsIScriptSecurityManager::NO_APP_ID; + return NS_OK; + } + + *aAppId = AppId(); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetAddonId(nsAString& aAddonId) +{ + aAddonId.Assign(mOriginAttributes.mAddonId); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetUserContextId(uint32_t* aUserContextId) +{ + *aUserContextId = UserContextId(); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) +{ + *aPrivateBrowsingId = PrivateBrowsingId(); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement) +{ + *aIsInIsolatedMozBrowserElement = IsInIsolatedMozBrowserElement(); + return NS_OK; +} + +NS_IMETHODIMP +BasePrincipal::GetUnknownAppId(bool* aUnknownAppId) +{ + *aUnknownAppId = AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID; + return NS_OK; +} + +bool +BasePrincipal::AddonHasPermission(const nsAString& aPerm) +{ + if (mOriginAttributes.mAddonId.IsEmpty()) { + return false; + } + nsCOMPtr aps = + do_GetService("@mozilla.org/addons/policy-service;1"); + NS_ENSURE_TRUE(aps, false); + + bool retval = false; + nsresult rv = aps->AddonHasPermission(mOriginAttributes.mAddonId, aPerm, &retval); + NS_ENSURE_SUCCESS(rv, false); + return retval; +} + +already_AddRefed +BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const PrincipalOriginAttributes& aAttrs) +{ + // If the URI is supposed to inherit the security context of whoever loads it, + // we shouldn't make a codebase principal for it. + bool inheritsPrincipal; + nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT, + &inheritsPrincipal); + if (NS_FAILED(rv) || inheritsPrincipal) { + return nsNullPrincipal::Create(aAttrs); + } + + // Check whether the URI knows what its principal is supposed to be. + nsCOMPtr uriPrinc = do_QueryInterface(aURI); + if (uriPrinc) { + nsCOMPtr principal; + uriPrinc->GetPrincipal(getter_AddRefs(principal)); + if (!principal) { + return nsNullPrincipal::Create(aAttrs); + } + RefPtr concrete = Cast(principal); + return concrete.forget(); + } + + // Mint a codebase principal. + RefPtr codebase = new nsPrincipal(); + rv = codebase->Init(aURI, aAttrs); + NS_ENSURE_SUCCESS(rv, nullptr); + return codebase.forget(); +} + +already_AddRefed +BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin) +{ + MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING("[")), + "CreateCodebasePrincipal does not support System and Expanded principals"); + + MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")), + "CreateCodebasePrincipal does not support nsNullPrincipal"); + + nsAutoCString originNoSuffix; + mozilla::PrincipalOriginAttributes attrs; + if (!attrs.PopulateFromOrigin(aOrigin, originNoSuffix)) { + return nullptr; + } + + nsCOMPtr uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix); + NS_ENSURE_SUCCESS(rv, nullptr); + + return BasePrincipal::CreateCodebasePrincipal(uri, attrs); +} + +already_AddRefed +BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain() +{ + PrincipalOriginAttributes attrs = OriginAttributesRef(); + attrs.StripUserContextIdAndFirstPartyDomain(); + + nsAutoCString originNoSuffix; + nsresult rv = GetOriginNoSuffix(originNoSuffix); + NS_ENSURE_SUCCESS(rv, nullptr); + + nsCOMPtr uri; + rv = NS_NewURI(getter_AddRefs(uri), originNoSuffix); + NS_ENSURE_SUCCESS(rv, nullptr); + + return BasePrincipal::CreateCodebasePrincipal(uri, attrs); +} + +bool +BasePrincipal::AddonAllowsLoad(nsIURI* aURI) +{ + if (mOriginAttributes.mAddonId.IsEmpty()) { + return false; + } + + nsCOMPtr aps = do_GetService("@mozilla.org/addons/policy-service;1"); + NS_ENSURE_TRUE(aps, false); + + bool allowed = false; + nsresult rv = aps->AddonMayLoadURI(mOriginAttributes.mAddonId, aURI, &allowed); + return NS_SUCCEEDED(rv) && allowed; +} + +} // namespace mozilla diff --git a/caps/BasePrincipal.h b/caps/BasePrincipal.h new file mode 100644 index 000000000..a2cc219bb --- /dev/null +++ b/caps/BasePrincipal.h @@ -0,0 +1,342 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_BasePrincipal_h +#define mozilla_BasePrincipal_h + +#include "nsIPrincipal.h" +#include "nsIScriptSecurityManager.h" +#include "nsJSPrincipals.h" + +#include "mozilla/Attributes.h" +#include "mozilla/dom/ChromeUtilsBinding.h" + +class nsIContentSecurityPolicy; +class nsIObjectOutputStream; +class nsIObjectInputStream; +class nsIURI; + +class nsExpandedPrincipal; + +namespace mozilla { + +class GenericOriginAttributes; + +// Base OriginAttributes class. This has several subclass flavors, and is not +// directly constructable itself. +class OriginAttributes : public dom::OriginAttributesDictionary +{ +public: + bool operator==(const OriginAttributes& aOther) const + { + return mAppId == aOther.mAppId && + mInIsolatedMozBrowser == aOther.mInIsolatedMozBrowser && + mAddonId == aOther.mAddonId && + mUserContextId == aOther.mUserContextId && + mPrivateBrowsingId == aOther.mPrivateBrowsingId && + mFirstPartyDomain == aOther.mFirstPartyDomain; + } + bool operator!=(const OriginAttributes& aOther) const + { + return !(*this == aOther); + } + + // Serializes/Deserializes non-default values into the suffix format, i.e. + // |!key1=value1&key2=value2|. If there are no non-default attributes, this + // returns an empty string. + void CreateSuffix(nsACString& aStr) const; + + // Don't use this method for anything else than debugging! + void CreateAnonymizedSuffix(nsACString& aStr) const; + + MOZ_MUST_USE bool PopulateFromSuffix(const nsACString& aStr); + + // Populates the attributes from a string like + // |uri!key1=value1&key2=value2| and returns the uri without the suffix. + MOZ_MUST_USE bool PopulateFromOrigin(const nsACString& aOrigin, + nsACString& aOriginNoSuffix); + + // Helper function to match mIsPrivateBrowsing to existing private browsing + // flags. Once all other flags are removed, this can be removed too. + void SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing); + + void SetFromGenericAttributes(const GenericOriginAttributes& aAttrs); + + // check if "privacy.firstparty.isolate" is enabled. + static bool IsFirstPartyEnabled(); + +protected: + OriginAttributes() {} + explicit OriginAttributes(const OriginAttributesDictionary& aOther) + : OriginAttributesDictionary(aOther) {} +}; + +class PrincipalOriginAttributes; +class DocShellOriginAttributes; +class NeckoOriginAttributes; + +// Various classes in Gecko contain OriginAttributes members, and those +// OriginAttributes get propagated to other classes according to certain rules. +// For example, the OriginAttributes on the docshell affect the OriginAttributes +// for the principal of a document loaded inside it, whose OriginAttributes in +// turn affect those of network loads and child docshells. To codify and +// centralize these rules, we introduce separate subclasses for the different +// flavors, and a variety of InheritFrom* methods to implement the transfer +// behavior. + +// For OriginAttributes stored on principals. +class PrincipalOriginAttributes : public OriginAttributes +{ +public: + PrincipalOriginAttributes() {} + PrincipalOriginAttributes(uint32_t aAppId, bool aInIsolatedMozBrowser) + { + mAppId = aAppId; + mInIsolatedMozBrowser = aInIsolatedMozBrowser; + } + + // Inheriting OriginAttributes from docshell to document when user navigates. + // + // @param aAttrs Origin Attributes of the docshell. + // @param aURI The URI of the document. + void InheritFromDocShellToDoc(const DocShellOriginAttributes& aAttrs, + const nsIURI* aURI); + + // Inherit OriginAttributes from Necko. + void InheritFromNecko(const NeckoOriginAttributes& aAttrs); + + void StripUserContextIdAndFirstPartyDomain(); +}; + +// For OriginAttributes stored on docshells / loadcontexts / browsing contexts. +class DocShellOriginAttributes : public OriginAttributes +{ +public: + DocShellOriginAttributes() {} + DocShellOriginAttributes(uint32_t aAppId, bool aInIsolatedMozBrowser) + { + mAppId = aAppId; + mInIsolatedMozBrowser = aInIsolatedMozBrowser; + } + + // Inheriting OriginAttributes from document to child docshell when an + // \n' + + '\n' + + ''; + + var iframes = document.getElementsByTagName("iframe"); + var promises = [] + for (var i = 0; i < promises.length; ++i) { + promises.push(new Promise(resolve => { + iframes[i].addEventListener("load", resolve); + })); + } + + return Promise.all(promises); +}); + +var prefs = new Promise(resolve => { + SpecialPowers.pushPrefEnv( + { set: [[ "dom.mozBrowserFramesEnabled", true ], + [ "dom.ipc.browser_frames.oop_by_default", false ]] }, + resolve); +}); + + +
+
+
+ + diff --git a/caps/tests/mochitest/test_bug246699.html b/caps/tests/mochitest/test_bug246699.html new file mode 100644 index 000000000..bb733e5df --- /dev/null +++ b/caps/tests/mochitest/test_bug246699.html @@ -0,0 +1,65 @@ + + + + + Test for Bug 246699 + + + + +Mozilla Bug 246699 +

+ +
+
+
+ + + diff --git a/caps/tests/mochitest/test_bug292789.html b/caps/tests/mochitest/test_bug292789.html new file mode 100644 index 000000000..291ba00c1 --- /dev/null +++ b/caps/tests/mochitest/test_bug292789.html @@ -0,0 +1,105 @@ + + + + + Test for Bug 292789 + + + + +Mozilla Bug 292789 +

+ +
+
+
+ + diff --git a/caps/tests/mochitest/test_bug423375.html b/caps/tests/mochitest/test_bug423375.html new file mode 100644 index 000000000..1cd2a7a82 --- /dev/null +++ b/caps/tests/mochitest/test_bug423375.html @@ -0,0 +1,44 @@ + + + + + Test for Bug 423375 + + + + +Mozilla Bug 423375 +

+ +
+
+
+ + + diff --git a/caps/tests/mochitest/test_bug470804.html b/caps/tests/mochitest/test_bug470804.html new file mode 100644 index 000000000..9ac88c8d7 --- /dev/null +++ b/caps/tests/mochitest/test_bug470804.html @@ -0,0 +1,41 @@ + + + + + Test for Bug 470804 + + + + +Mozilla Bug 470804 +

+ +
+
+
+ + diff --git a/caps/tests/mochitest/test_bug995943.xul b/caps/tests/mochitest/test_bug995943.xul new file mode 100644 index 000000000..e9eebb736 --- /dev/null +++ b/caps/tests/mochitest/test_bug995943.xul @@ -0,0 +1,115 @@ + + + + + + +