Bug 663570 - MetaCSP Part 4: Speculative parser changes (r=bz)

This commit is contained in:
Christoph Kerschbaumer 2015-11-14 19:28:51 -08:00
parent 745806b307
commit 320edcc5a0
5 changed files with 64 additions and 0 deletions

View File

@ -27,6 +27,9 @@ nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
case eSpeculativeLoadBase: case eSpeculativeLoadBase:
aExecutor->SetSpeculationBase(mUrl); aExecutor->SetSpeculationBase(mUrl);
break; break;
case eSpeculativeLoadCSP:
aExecutor->AddSpeculationCSP(mMetaCSP);
break;
case eSpeculativeLoadMetaReferrer: case eSpeculativeLoadMetaReferrer:
aExecutor->SetSpeculationReferrerPolicy(mReferrerPolicy); aExecutor->SetSpeculationReferrerPolicy(mReferrerPolicy);
break; break;

View File

@ -15,6 +15,7 @@ enum eHtml5SpeculativeLoad {
eSpeculativeLoadUninitialized, eSpeculativeLoadUninitialized,
#endif #endif
eSpeculativeLoadBase, eSpeculativeLoadBase,
eSpeculativeLoadCSP,
eSpeculativeLoadMetaReferrer, eSpeculativeLoadMetaReferrer,
eSpeculativeLoadImage, eSpeculativeLoadImage,
eSpeculativeLoadOpenPicture, eSpeculativeLoadOpenPicture,
@ -41,6 +42,14 @@ class nsHtml5SpeculativeLoad {
mUrl.Assign(aUrl); mUrl.Assign(aUrl);
} }
inline void InitMetaCSP(const nsAString& aCSP) {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadCSP;
mMetaCSP.Assign(
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aCSP));
}
inline void InitMetaReferrerPolicy(const nsAString& aReferrerPolicy) { inline void InitMetaReferrerPolicy(const nsAString& aReferrerPolicy) {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
@ -187,6 +196,8 @@ class nsHtml5SpeculativeLoad {
eHtml5SpeculativeLoad mOpCode; eHtml5SpeculativeLoad mOpCode;
nsString mUrl; nsString mUrl;
nsString mReferrerPolicy; nsString mReferrerPolicy;
nsString mMetaCSP;
/** /**
* If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript[FromHead] * If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript[FromHead]
* then this is the value of the "charset" attribute. For * then this is the value of the "charset" attribute. For

View File

@ -236,6 +236,14 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
} }
} else if (nsHtml5Atoms::meta == aName) { } else if (nsHtml5Atoms::meta == aName) {
if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString( if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
"content-security-policy",
aAttributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
nsString* csp = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
if (csp) {
mSpeculativeLoadQueue.AppendElement()->InitMetaCSP(*csp);
}
}
else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
"referrer", "referrer",
aAttributes->getValue(nsHtml5AttributeName::ATTR_NAME))) { aAttributes->getValue(nsHtml5AttributeName::ATTR_NAME))) {
nsString* referrerPolicy = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT); nsString* referrerPolicy = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);

View File

@ -6,13 +6,16 @@
#include "mozilla/DebugOnly.h" #include "mozilla/DebugOnly.h"
#include "mozilla/Likely.h" #include "mozilla/Likely.h"
#include "mozilla/dom/nsCSPService.h"
#include "nsError.h" #include "nsError.h"
#include "nsHtml5TreeOpExecutor.h" #include "nsHtml5TreeOpExecutor.h"
#include "nsScriptLoader.h" #include "nsScriptLoader.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeItem.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "nsIDOMDocument.h"
#include "nsIScriptGlobalObject.h" #include "nsIScriptGlobalObject.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsIWebShellServices.h" #include "nsIWebShellServices.h"
@ -1014,6 +1017,43 @@ nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(const nsAString& aReferrerPo
return SetSpeculationReferrerPolicy(policy); return SetSpeculationReferrerPolicy(policy);
} }
void
nsHtml5TreeOpExecutor::AddSpeculationCSP(const nsAString& aCSP)
{
if (!CSPService::sCSPEnabled) {
return;
}
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsIPrincipal* principal = mDocument->NodePrincipal();
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp;
nsresult rv = principal->GetPreloadCsp(getter_AddRefs(preloadCsp));
NS_ENSURE_SUCCESS_VOID(rv);
if (!preloadCsp) {
preloadCsp = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
NS_ENSURE_SUCCESS_VOID(rv);
// Store the request context for violation reports
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument);
rv = preloadCsp->SetRequestContext(domDoc, nullptr);
NS_ENSURE_SUCCESS_VOID(rv);
// set the new csp
rv = principal->SetPreloadCsp(preloadCsp);
NS_ENSURE_SUCCESS_VOID(rv);
}
// please note that meta CSPs and CSPs delivered through a header need
// to be joined together.
rv = preloadCsp->AppendPolicy(aCSP,
false, // csp via meta tag can not be report only
true); // delivered through the meta tag
NS_ENSURE_SUCCESS_VOID(rv);
mDocument->ApplySettingsFromCSP(true);
}
void void
nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy) nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy)
{ {

View File

@ -275,6 +275,8 @@ class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
void SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy); void SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy);
void SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy); void SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy);
void AddSpeculationCSP(const nsAString& aCSP);
void AddBase(const nsAString& aURL); void AddBase(const nsAString& aURL);
static void InitializeStatics(); static void InitializeStatics();