diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index 13d6233bbaee..4d403587fcaf 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -314,17 +314,27 @@ nsresult nsCSPContext::InitFromOther(nsCSPContext* aOtherContext) { mSkipAllowInlineStyleCheck = aOtherContext->mSkipAllowInlineStyleCheck; + // This policy was already parsed somewhere else, don't emit parsing errors. + mSuppressParserLogMessages = true; for (auto policy : aOtherContext->mPolicies) { nsAutoString policyStr; policy->toString(policyStr); AppendPolicy(policyStr, policy->getReportOnlyFlag(), policy->getDeliveredViaMetaTagFlag()); } + + mSuppressParserLogMessages = aOtherContext->mSuppressParserLogMessages; + mIPCPolicies = aOtherContext->mIPCPolicies.Clone(); return NS_OK; } void nsCSPContext::EnsureIPCPoliciesRead() { + // Most likely the parser errors already happened before serializing + // the policy for IPC. + bool previous = mSuppressParserLogMessages; + mSuppressParserLogMessages = true; + if (mIPCPolicies.Length() > 0) { nsresult rv; for (auto& policy : mIPCPolicies) { @@ -334,6 +344,8 @@ void nsCSPContext::EnsureIPCPoliciesRead() { } mIPCPolicies.Clear(); } + + mSuppressParserLogMessages = previous; } NS_IMETHODIMP @@ -435,7 +447,8 @@ nsCSPContext::AppendPolicy(const nsAString& aPolicyString, bool aReportOnly, } nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy( - aPolicyString, mSelfURI, aReportOnly, this, aDeliveredViaMetaTag); + aPolicyString, mSelfURI, aReportOnly, this, aDeliveredViaMetaTag, + mSuppressParserLogMessages); if (policy) { if (policy->hasDirective( nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE)) { diff --git a/dom/security/nsCSPContext.h b/dom/security/nsCSPContext.h index f9a5580b4cd4..85d286f90165 100644 --- a/dom/security/nsCSPContext.h +++ b/dom/security/nsCSPContext.h @@ -58,6 +58,10 @@ class nsCSPContext : public nsIContentSecurityPolicy { // Init a CSP from a different CSP nsresult InitFromOther(nsCSPContext* otherContext); + // Used to suppress errors and warnings produced by the parser. + // Use this when doing an one-off parsing of the CSP. + void SuppressParserLogMessages() { mSuppressParserLogMessages = true; } + /** * SetRequestContextWithDocument() needs to be called before the * innerWindowID is initialized on the document. Use this function @@ -182,6 +186,8 @@ class nsCSPContext : public nsIContentSecurityPolicy { nsWeakPtr mLoadingContext; nsCOMPtr mLoadingPrincipal; + bool mSuppressParserLogMessages = false; + // helper members used to queue up web console messages till // the windowID becomes available. see flushConsoleMessages() nsTArray mConsoleMsgQueue; diff --git a/dom/security/nsCSPParser.cpp b/dom/security/nsCSPParser.cpp index 6eabc471ac52..8fa1bca6d60f 100644 --- a/dom/security/nsCSPParser.cpp +++ b/dom/security/nsCSPParser.cpp @@ -40,7 +40,8 @@ static const uint32_t kHashSourceValidFnsLen = 3; /* ===== nsCSPParser ==================== */ nsCSPParser::nsCSPParser(policyTokens& aTokens, nsIURI* aSelfURI, - nsCSPContext* aCSPContext, bool aDeliveredViaMetaTag) + nsCSPContext* aCSPContext, bool aDeliveredViaMetaTag, + bool aSuppressLogMessages) : mCurChar(nullptr), mEndChar(nullptr), mHasHashOrNonce(false), @@ -57,7 +58,8 @@ nsCSPParser::nsCSPParser(policyTokens& aTokens, nsIURI* aSelfURI, mSelfURI(aSelfURI), mPolicy(nullptr), mCSPContext(aCSPContext), - mDeliveredViaMetaTag(aDeliveredViaMetaTag) { + mDeliveredViaMetaTag(aDeliveredViaMetaTag), + mSuppressLogMessages(aSuppressLogMessages) { CSPPARSERLOG(("nsCSPParser::nsCSPParser")); } @@ -161,6 +163,11 @@ void nsCSPParser::logWarningErrorToConsole(uint32_t aSeverityFlag, const char* aProperty, const nsTArray& aParams) { CSPPARSERLOG(("nsCSPParser::logWarningErrorToConsole: %s", aProperty)); + + if (mSuppressLogMessages) { + return; + } + // send console messages off to the context and let the context // deal with it (potentially messages need to be queued up) mCSPContext->logToConsole(aProperty, aParams, @@ -1221,7 +1228,8 @@ nsCSPPolicy* nsCSPParser::policy() { nsCSPPolicy* nsCSPParser::parseContentSecurityPolicy( const nsAString& aPolicyString, nsIURI* aSelfURI, bool aReportOnly, - nsCSPContext* aCSPContext, bool aDeliveredViaMetaTag) { + nsCSPContext* aCSPContext, bool aDeliveredViaMetaTag, + bool aSuppressLogMessages) { if (CSPPARSERLOGENABLED()) { CSPPARSERLOG(("nsCSPParser::parseContentSecurityPolicy, policy: %s", NS_ConvertUTF16toUTF8(aPolicyString).get())); @@ -1244,7 +1252,8 @@ nsCSPPolicy* nsCSPParser::parseContentSecurityPolicy( nsTArray > tokens; PolicyTokenizer::tokenizePolicy(aPolicyString, tokens); - nsCSPParser parser(tokens, aSelfURI, aCSPContext, aDeliveredViaMetaTag); + nsCSPParser parser(tokens, aSelfURI, aCSPContext, aDeliveredViaMetaTag, + aSuppressLogMessages); // Start the parser to generate a new CSPPolicy using the generated tokens. nsCSPPolicy* policy = parser.policy(); diff --git a/dom/security/nsCSPParser.h b/dom/security/nsCSPParser.h index a3b08e9352e2..21679d86a051 100644 --- a/dom/security/nsCSPParser.h +++ b/dom/security/nsCSPParser.h @@ -53,11 +53,13 @@ class nsCSPParser { nsIURI* aSelfURI, bool aReportOnly, nsCSPContext* aCSPContext, - bool aDeliveredViaMetaTag); + bool aDeliveredViaMetaTag, + bool aSuppressLogMessages); private: nsCSPParser(policyTokens& aTokens, nsIURI* aSelfURI, - nsCSPContext* aCSPContext, bool aDeliveredViaMetaTag); + nsCSPContext* aCSPContext, bool aDeliveredViaMetaTag, + bool aSuppressLogMessages); ~nsCSPParser(); @@ -209,6 +211,7 @@ class nsCSPParser { nsCSPPolicy* mPolicy; nsCSPContext* mCSPContext; // used for console logging bool mDeliveredViaMetaTag; + bool mSuppressLogMessages; }; #endif /* nsCSPParser_h___ */ diff --git a/dom/security/nsContentSecurityUtils.cpp b/dom/security/nsContentSecurityUtils.cpp index 8e4beeb3b420..5375358b2e2a 100644 --- a/dom/security/nsContentSecurityUtils.cpp +++ b/dom/security/nsContentSecurityUtils.cpp @@ -1005,6 +1005,11 @@ nsresult CheckCSPFrameAncestorPolicy(nsIChannel* aChannel, } RefPtr csp = new nsCSPContext(); + // This CSPContext is only used for checking frame-ancestors, we + // will parse the CSP again anyway. (Unless this blocks the load, but + // parser warnings aren't really important in that case) + csp->SuppressParserLogMessages(); + nsCOMPtr selfURI; nsAutoString referrerSpec; if (httpChannel) { diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp index 17d2c7d96c19..da570e5b6dba 100644 --- a/parser/html/nsHtml5TreeOpExecutor.cpp +++ b/parser/html/nsHtml5TreeOpExecutor.cpp @@ -1374,7 +1374,9 @@ void nsHtml5TreeOpExecutor::AddSpeculationCSP(const nsAString& aCSP) { nsresult rv = NS_OK; nsCOMPtr preloadCsp = mDocument->GetPreloadCsp(); if (!preloadCsp) { - preloadCsp = new nsCSPContext(); + RefPtr csp = new nsCSPContext(); + csp->SuppressParserLogMessages(); + preloadCsp = csp; rv = preloadCsp->SetRequestContextWithDocument(mDocument); NS_ENSURE_SUCCESS_VOID(rv); }