Loading caps/moz.build +1 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ LOCAL_INCLUDES += [ '/docshell/base', '/dom/base', '/js/xpconnect/src', '/netwerk/base', ] if CONFIG['ENABLE_TESTS']: Loading caps/nsScriptSecurityManager.cpp +61 −35 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include "nsIWindowWatcher.h" #include "nsIConsoleService.h" #include "nsIObserverService.h" #include "nsIOService.h" #include "nsIContent.h" #include "nsDOMJSUtils.h" #include "nsAboutProtocolUtils.h" Loading Loading @@ -265,6 +266,61 @@ nsScriptSecurityManager::GetChannelResultPrincipalIfNotSandboxed(nsIChannel* aCh /*aIgnoreSandboxing*/ true); } static void InheritAndSetCSPOnPrincipalIfNeeded(nsIChannel* aChannel, nsIPrincipal* aPrincipal) { // loading a data: URI into an iframe, or loading frame[srcdoc] need // to inherit the CSP (see Bug 1073952, 1381761). MOZ_ASSERT(aChannel && aPrincipal, "need a valid channel and principal"); if (!aChannel) { return; } nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo(); if (!loadInfo || loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_SUBDOCUMENT) { return; } nsCOMPtr<nsIURI> uri; nsresult rv = aChannel->GetURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS_VOID(rv); nsAutoCString URISpec; rv = uri->GetSpec(URISpec); NS_ENSURE_SUCCESS_VOID(rv); bool isSrcDoc = URISpec.EqualsLiteral("about:srcdoc"); bool isData = (NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData); if (!isSrcDoc && !isData) { return; } nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit(); if (!principalToInherit) { principalToInherit = loadInfo->TriggeringPrincipal(); } nsCOMPtr<nsIContentSecurityPolicy> originalCSP; principalToInherit->GetCsp(getter_AddRefs(originalCSP)); if (!originalCSP) { return; } // if the principalToInherit had a CSP, add it to the before // created NullPrincipal (unless it already has one) MOZ_ASSERT(aPrincipal->GetIsNullPrincipal(), "inheriting the CSP only valid for NullPrincipal"); nsCOMPtr<nsIContentSecurityPolicy> nullPrincipalCSP; aPrincipal->GetCsp(getter_AddRefs(nullPrincipalCSP)); if (nullPrincipalCSP) { MOZ_ASSERT(nullPrincipalCSP == originalCSP, "There should be no other CSP here."); // CSPs are equal, no need to set it again. return; } aPrincipal->SetCsp(originalCSP); } nsresult nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, nsIPrincipal** aPrincipal, Loading Loading @@ -295,40 +351,7 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, if (!aIgnoreSandboxing && loadInfo->GetLoadingSandboxed()) { MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSandboxedLoadingPrincipal(aPrincipal))); MOZ_ASSERT(*aPrincipal); // if the new NullPrincipal (above) loads an iframe[srcdoc], we // need to inherit an existing CSP to avoid bypasses (bug 1073952). // We continue inheriting for nested frames with e.g., data: URLs. if (loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_SUBDOCUMENT) { nsCOMPtr<nsIURI> uri; aChannel->GetURI(getter_AddRefs(uri)); nsAutoCString URISpec; uri->GetSpec(URISpec); bool isData = (NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData); if (URISpec.EqualsLiteral("about:srcdoc") || isData) { nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit(); if (!principalToInherit) { principalToInherit = loadInfo->TriggeringPrincipal(); } nsCOMPtr<nsIContentSecurityPolicy> originalCSP; principalToInherit->GetCsp(getter_AddRefs(originalCSP)); if (originalCSP) { // if the principalToInherit had a CSP, // add it to the newly created NullPrincipal // (unless it already has one) nsCOMPtr<nsIContentSecurityPolicy> nullPrincipalCSP; (*aPrincipal)->GetCsp(getter_AddRefs(nullPrincipalCSP)); if (nullPrincipalCSP) { MOZ_ASSERT(nullPrincipalCSP == originalCSP, "There should be no other CSP here."); // CSPs are equal, no need to set it again. return NS_OK; } else { nsresult rv = (*aPrincipal)->SetCsp(originalCSP); NS_ENSURE_SUCCESS(rv, rv); } } } } InheritAndSetCSPOnPrincipalIfNeeded(aChannel, *aPrincipal); return NS_OK; } Loading Loading @@ -376,7 +399,10 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, } } } return GetChannelURIPrincipal(aChannel, aPrincipal); nsresult rv = GetChannelURIPrincipal(aChannel, aPrincipal); NS_ENSURE_SUCCESS(rv, rv); InheritAndSetCSPOnPrincipalIfNeeded(aChannel, *aPrincipal); return NS_OK; } /* The principal of the URI that this channel is loading. This is never Loading Loading
caps/moz.build +1 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ LOCAL_INCLUDES += [ '/docshell/base', '/dom/base', '/js/xpconnect/src', '/netwerk/base', ] if CONFIG['ENABLE_TESTS']: Loading
caps/nsScriptSecurityManager.cpp +61 −35 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include "nsIWindowWatcher.h" #include "nsIConsoleService.h" #include "nsIObserverService.h" #include "nsIOService.h" #include "nsIContent.h" #include "nsDOMJSUtils.h" #include "nsAboutProtocolUtils.h" Loading Loading @@ -265,6 +266,61 @@ nsScriptSecurityManager::GetChannelResultPrincipalIfNotSandboxed(nsIChannel* aCh /*aIgnoreSandboxing*/ true); } static void InheritAndSetCSPOnPrincipalIfNeeded(nsIChannel* aChannel, nsIPrincipal* aPrincipal) { // loading a data: URI into an iframe, or loading frame[srcdoc] need // to inherit the CSP (see Bug 1073952, 1381761). MOZ_ASSERT(aChannel && aPrincipal, "need a valid channel and principal"); if (!aChannel) { return; } nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo(); if (!loadInfo || loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_SUBDOCUMENT) { return; } nsCOMPtr<nsIURI> uri; nsresult rv = aChannel->GetURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS_VOID(rv); nsAutoCString URISpec; rv = uri->GetSpec(URISpec); NS_ENSURE_SUCCESS_VOID(rv); bool isSrcDoc = URISpec.EqualsLiteral("about:srcdoc"); bool isData = (NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData); if (!isSrcDoc && !isData) { return; } nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit(); if (!principalToInherit) { principalToInherit = loadInfo->TriggeringPrincipal(); } nsCOMPtr<nsIContentSecurityPolicy> originalCSP; principalToInherit->GetCsp(getter_AddRefs(originalCSP)); if (!originalCSP) { return; } // if the principalToInherit had a CSP, add it to the before // created NullPrincipal (unless it already has one) MOZ_ASSERT(aPrincipal->GetIsNullPrincipal(), "inheriting the CSP only valid for NullPrincipal"); nsCOMPtr<nsIContentSecurityPolicy> nullPrincipalCSP; aPrincipal->GetCsp(getter_AddRefs(nullPrincipalCSP)); if (nullPrincipalCSP) { MOZ_ASSERT(nullPrincipalCSP == originalCSP, "There should be no other CSP here."); // CSPs are equal, no need to set it again. return; } aPrincipal->SetCsp(originalCSP); } nsresult nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, nsIPrincipal** aPrincipal, Loading Loading @@ -295,40 +351,7 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, if (!aIgnoreSandboxing && loadInfo->GetLoadingSandboxed()) { MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSandboxedLoadingPrincipal(aPrincipal))); MOZ_ASSERT(*aPrincipal); // if the new NullPrincipal (above) loads an iframe[srcdoc], we // need to inherit an existing CSP to avoid bypasses (bug 1073952). // We continue inheriting for nested frames with e.g., data: URLs. if (loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_SUBDOCUMENT) { nsCOMPtr<nsIURI> uri; aChannel->GetURI(getter_AddRefs(uri)); nsAutoCString URISpec; uri->GetSpec(URISpec); bool isData = (NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData); if (URISpec.EqualsLiteral("about:srcdoc") || isData) { nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit(); if (!principalToInherit) { principalToInherit = loadInfo->TriggeringPrincipal(); } nsCOMPtr<nsIContentSecurityPolicy> originalCSP; principalToInherit->GetCsp(getter_AddRefs(originalCSP)); if (originalCSP) { // if the principalToInherit had a CSP, // add it to the newly created NullPrincipal // (unless it already has one) nsCOMPtr<nsIContentSecurityPolicy> nullPrincipalCSP; (*aPrincipal)->GetCsp(getter_AddRefs(nullPrincipalCSP)); if (nullPrincipalCSP) { MOZ_ASSERT(nullPrincipalCSP == originalCSP, "There should be no other CSP here."); // CSPs are equal, no need to set it again. return NS_OK; } else { nsresult rv = (*aPrincipal)->SetCsp(originalCSP); NS_ENSURE_SUCCESS(rv, rv); } } } } InheritAndSetCSPOnPrincipalIfNeeded(aChannel, *aPrincipal); return NS_OK; } Loading Loading @@ -376,7 +399,10 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, } } } return GetChannelURIPrincipal(aChannel, aPrincipal); nsresult rv = GetChannelURIPrincipal(aChannel, aPrincipal); NS_ENSURE_SUCCESS(rv, rv); InheritAndSetCSPOnPrincipalIfNeeded(aChannel, *aPrincipal); return NS_OK; } /* The principal of the URI that this channel is loading. This is never Loading