Bug 1534971: Add helper function within CSP to check if two CSPs are equal. r=jkt

Differential Revision: https://phabricator.services.mozilla.com/D23567

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Christoph Kerschbaumer 2019-03-15 12:20:52 +00:00
parent 24dc1bfecc
commit 23b1d42b45
4 changed files with 42 additions and 47 deletions

View File

@ -62,6 +62,7 @@
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/NullPrincipal.h"
#include <stdint.h>
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StaticPtr.h"
@ -289,26 +290,7 @@ static void InheritAndSetCSPOnPrincipalIfNeeded(nsIChannel* aChannel,
nsCOMPtr<nsIContentSecurityPolicy> nullPrincipalCSP;
aPrincipal->GetCsp(getter_AddRefs(nullPrincipalCSP));
if (nullPrincipalCSP) {
#ifdef DEBUG
{
uint32_t nullPrincipalCSPCount = 0;
nullPrincipalCSP->GetPolicyCount(&nullPrincipalCSPCount);
uint32_t originalCSPCount = 0;
originalCSP->GetPolicyCount(&originalCSPCount);
MOZ_ASSERT(nullPrincipalCSPCount == originalCSPCount,
"There should be no other CSP here.");
nsAutoString nullPrincipalCSPStr, originalCSPStr;
for (uint32_t i = 0; i < originalCSPCount; ++i) {
originalCSP->GetPolicyString(i, originalCSPStr);
nullPrincipalCSP->GetPolicyString(i, nullPrincipalCSPStr);
MOZ_ASSERT(originalCSPStr.Equals(nullPrincipalCSPStr),
"There should be no other CSP string here.");
}
}
#endif
MOZ_ASSERT(nsCSPContext::Equals(originalCSP, nullPrincipalCSP));
// CSPs are equal, no need to set it again.
return;
}

View File

@ -59,6 +59,7 @@
#include "mozilla/dom/TabGroup.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/ChildSHistory.h"
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/net/ReferrerPolicy.h"
@ -9912,34 +9913,9 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
// holds upgrade-insecure-requests.
nsCOMPtr<nsIContentSecurityPolicy> csp;
aLoadState->TriggeringPrincipal()->GetCsp(getter_AddRefs(csp));
#ifdef DEBUG
{
// After Bug 965637 we move the CSP from the Principal into the Client,
// hence we need an explicit CSP argument passed to docshell. Let's make
// sure the explicit CSP is the same as the CSP on the Principal.
uint32_t principalCSPCount = 0;
if (csp) {
csp->GetPolicyCount(&principalCSPCount);
}
nsCOMPtr<nsIContentSecurityPolicy> argsCSP = aLoadState->Csp();
uint32_t argCSPCount = 0;
if (argsCSP) {
argsCSP->GetPolicyCount(&argCSPCount);
}
MOZ_ASSERT(principalCSPCount == argCSPCount,
"Different PolicyCount for CSP as arg and Principal");
nsAutoString principalPolicyStr, argPolicyStr;
for (uint32_t i = 0; i < principalCSPCount; ++i) {
csp->GetPolicyString(i, principalPolicyStr);
argsCSP->GetPolicyString(i, argPolicyStr);
MOZ_ASSERT(principalPolicyStr.Equals(argPolicyStr),
"Different PolicyStr for CSP as arg and Principal");
}
}
nsCOMPtr<nsIContentSecurityPolicy> argsCSP = aLoadState->Csp();
MOZ_ASSERT(nsCSPContext::Equals(csp, argsCSP));
#endif
if (csp) {

View File

@ -253,6 +253,40 @@ nsCSPContext::~nsCSPContext() {
}
}
/* static */
bool nsCSPContext::Equals(nsIContentSecurityPolicy* aCSP,
nsIContentSecurityPolicy* aOtherCSP) {
if (aCSP == aOtherCSP) {
// fast path for pointer equality
return true;
}
uint32_t policyCount = 0;
if (aCSP) {
aCSP->GetPolicyCount(&policyCount);
}
uint32_t otherPolicyCount = 0;
if (aOtherCSP) {
aOtherCSP->GetPolicyCount(&otherPolicyCount);
}
if (policyCount != otherPolicyCount) {
return false;
}
nsAutoString policyStr, otherPolicyStr;
for (uint32_t i = 0; i < policyCount; ++i) {
aCSP->GetPolicyString(i, policyStr);
aOtherCSP->GetPolicyString(i, otherPolicyStr);
if (!policyStr.Equals(otherPolicyStr)) {
return false;
}
}
return true;
}
nsresult nsCSPContext::InitFromOther(nsCSPContext* aOtherContext,
Document* aDoc, nsIPrincipal* aPrincipal) {
NS_ENSURE_ARG(aOtherContext);

View File

@ -54,6 +54,9 @@ class nsCSPContext : public nsIContentSecurityPolicy {
public:
nsCSPContext();
static bool Equals(nsIContentSecurityPolicy* aCSP,
nsIContentSecurityPolicy* aOtherCSP);
nsresult InitFromOther(nsCSPContext* otherContext,
mozilla::dom::Document* aDoc,
nsIPrincipal* aPrincipal);