diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index b2e5a19854..9a3b02f7f4 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -796,7 +796,7 @@ EventListenerManager::SetEventHandler(nsIAtom* aName, if (csp) { bool allowsInlineScript = true; - rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT, + rv = csp->GetAllowsInline(nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE, EmptyString(), // aNonce true, // aParserCreated (true because attribute event handler) aBody, diff --git a/dom/interfaces/security/nsIContentSecurityPolicy.idl b/dom/interfaces/security/nsIContentSecurityPolicy.idl index bdcbf908bf..f01bb69add 100644 --- a/dom/interfaces/security/nsIContentSecurityPolicy.idl +++ b/dom/interfaces/security/nsIContentSecurityPolicy.idl @@ -146,7 +146,7 @@ interface nsIContentSecurityPolicy : nsISerializable * Whether or not the effects of the inline style should be allowed * (block the rules if false). */ - boolean getAllowsInline(in nsContentPolicyType aContentPolicyType, + boolean getAllowsInline(in CSPDirective aContentPolicyType, in AString aNonce, in boolean aParserCreated, in AString aContent, diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp index 9a9541164f..aa7a3c3259 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -180,7 +180,7 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel, NS_ENSURE_SUCCESS(rv, rv); if (csp) { bool allowsInlineScript = true; - rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT, + rv = csp->GetAllowsInline(nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE, EmptyString(), // aNonce true, // aParserCreated EmptyString(), // aContent diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index 6c211d53f2..3fc8027660 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -1471,7 +1471,7 @@ CSPAllowsInlineScript(nsIScriptElement *aElement, nsIDocument *aDocument) aElement->GetScriptText(scriptText); bool allowInlineScript = false; - rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT, + rv = csp->GetAllowsInline(nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE, nonce, parserCreated, scriptText, aElement->GetScriptLineNumber(), aElement->GetScriptColumnNumber(), diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index 9eafd9498b..da0a942d01 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -469,7 +469,7 @@ nsCSPContext::GetAllowsEval(bool* outShouldReportViolation, *outAllowsEval = true; for (uint32_t i = 0; i < mPolicies.Length(); i++) { - if (!mPolicies[i]->allows(nsIContentPolicy::TYPE_SCRIPT, + if (!mPolicies[i]->allows(SCRIPT_SRC_DIRECTIVE, CSP_UNSAFE_EVAL, EmptyString(), false)) { @@ -486,7 +486,7 @@ nsCSPContext::GetAllowsEval(bool* outShouldReportViolation, // Helper function to report inline violations void -nsCSPContext::reportInlineViolation(nsContentPolicyType aContentType, +nsCSPContext::reportInlineViolation(CSPDirective aDirective, const nsAString& aNonce, const nsAString& aContent, const nsAString& aViolatedDirective, @@ -499,12 +499,12 @@ nsCSPContext::reportInlineViolation(nsContentPolicyType aContentType, // let's report the hash error; no need to report the unsafe-inline error // anymore. if (!aNonce.IsEmpty()) { - observerSubject = (aContentType == nsIContentPolicy::TYPE_SCRIPT) + observerSubject = (aDirective == SCRIPT_SRC_DIRECTIVE) ? NS_LITERAL_STRING(SCRIPT_NONCE_VIOLATION_OBSERVER_TOPIC) : NS_LITERAL_STRING(STYLE_NONCE_VIOLATION_OBSERVER_TOPIC); } else { - observerSubject = (aContentType == nsIContentPolicy::TYPE_SCRIPT) + observerSubject = (aDirective == SCRIPT_SRC_DIRECTIVE) ? NS_LITERAL_STRING(SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC) : NS_LITERAL_STRING(STYLE_HASH_VIOLATION_OBSERVER_TOPIC); } @@ -555,7 +555,7 @@ nsCSPContext::reportInlineViolation(nsContentPolicyType aContentType, } NS_IMETHODIMP -nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType, +nsCSPContext::GetAllowsInline(CSPDirective aDirective, const nsAString& aNonce, bool aParserCreated, const nsAString& aContent, @@ -565,11 +565,7 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType, { *outAllowsInline = true; - MOZ_ASSERT(aContentType == nsContentUtils::InternalContentPolicyTypeToExternal(aContentType), - "We should only see external content policy types here."); - - if (aContentType != nsIContentPolicy::TYPE_SCRIPT && - aContentType != nsIContentPolicy::TYPE_STYLESHEET) { + if (aDirective != SCRIPT_SRC_DIRECTIVE && aDirective != STYLE_SRC_DIRECTIVE) { MOZ_ASSERT(false, "can only allow inline for script or style"); return NS_OK; } @@ -577,8 +573,8 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType, // always iterate all policies, otherwise we might not send out all reports for (uint32_t i = 0; i < mPolicies.Length(); i++) { bool allowed = - mPolicies[i]->allows(aContentType, CSP_UNSAFE_INLINE, EmptyString(), aParserCreated) || - mPolicies[i]->allows(aContentType, CSP_NONCE, aNonce, aParserCreated); + mPolicies[i]->allows(aDirective, CSP_UNSAFE_INLINE, EmptyString(), aParserCreated) || + mPolicies[i]->allows(aDirective, CSP_NONCE, aNonce, aParserCreated); // If the inlined script or style is allowed by either unsafe-inline or the // nonce, go ahead and shortcut this loop. @@ -589,7 +585,7 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType, // Check if the csp-hash matches against the hash of the script. // If we don't have any content to check, block the script. if (!aContent.IsEmpty()) { - allowed = mPolicies[i]->allows(aContentType, CSP_HASH, aContent, aParserCreated); + allowed = mPolicies[i]->allows(aDirective, CSP_HASH, aContent, aParserCreated); } if (!allowed) { @@ -599,8 +595,8 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType, *outAllowsInline = false; } nsAutoString violatedDirective; - mPolicies[i]->getDirectiveStringForContentType(aContentType, violatedDirective); - reportInlineViolation(aContentType, + mPolicies[i]->getDirectiveStringForContentType(aDirective, violatedDirective); + reportInlineViolation(aDirective, aNonce, aContent, violatedDirective, @@ -641,17 +637,17 @@ nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType, * GetAllowsInline() and do not call this macro, hence we can pass 'false' * as the argument _aParserCreated_ to allows(). */ -#define CASE_CHECK_AND_REPORT(violationType, contentPolicyType, nonceOrHash, \ +#define CASE_CHECK_AND_REPORT(violationType, directive, nonceOrHash, \ keyword, observerTopic) \ case nsIContentSecurityPolicy::VIOLATION_TYPE_ ## violationType : \ PR_BEGIN_MACRO \ - if (!mPolicies[p]->allows(nsIContentPolicy::TYPE_ ## contentPolicyType, \ - keyword, nonceOrHash, false)) \ - { \ + static_assert(directive##_SRC_DIRECTIVE == SCRIPT_SRC_DIRECTIVE || \ + directive##_SRC_DIRECTIVE == STYLE_SRC_DIRECTIVE); \ + if (!mPolicies[p]->allows(directive##_SRC_DIRECTIVE, keyword, nonceOrHash, \ + false)) { \ nsAutoString violatedDirective; \ mPolicies[p]->getDirectiveStringForContentType( \ - nsIContentPolicy::TYPE_ ## contentPolicyType, \ - violatedDirective); \ + directive##_SRC_DIRECTIVE, violatedDirective); \ this->AsyncReportViolation(selfISupports, nullptr, violatedDirective, p, \ NS_LITERAL_STRING(observerTopic), aSourceFile,\ aScriptSample, aLineNum, aColumnNum); \ @@ -711,19 +707,19 @@ nsCSPContext::LogViolationDetails(uint16_t aViolationType, switch (aViolationType) { CASE_CHECK_AND_REPORT(EVAL, SCRIPT, NS_LITERAL_STRING(""), CSP_UNSAFE_EVAL, EVAL_VIOLATION_OBSERVER_TOPIC); - CASE_CHECK_AND_REPORT(INLINE_STYLE, STYLESHEET, NS_LITERAL_STRING(""), + CASE_CHECK_AND_REPORT(INLINE_STYLE, STYLE, NS_LITERAL_STRING(""), CSP_UNSAFE_INLINE, INLINE_STYLE_VIOLATION_OBSERVER_TOPIC); CASE_CHECK_AND_REPORT(INLINE_SCRIPT, SCRIPT, NS_LITERAL_STRING(""), CSP_UNSAFE_INLINE, INLINE_SCRIPT_VIOLATION_OBSERVER_TOPIC); CASE_CHECK_AND_REPORT(NONCE_SCRIPT, SCRIPT, aNonce, CSP_UNSAFE_INLINE, SCRIPT_NONCE_VIOLATION_OBSERVER_TOPIC); - CASE_CHECK_AND_REPORT(NONCE_STYLE, STYLESHEET, aNonce, + CASE_CHECK_AND_REPORT(NONCE_STYLE, STYLE, aNonce, CSP_UNSAFE_INLINE, STYLE_NONCE_VIOLATION_OBSERVER_TOPIC); CASE_CHECK_AND_REPORT(HASH_SCRIPT, SCRIPT, aContent, CSP_UNSAFE_INLINE, SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC); - CASE_CHECK_AND_REPORT(HASH_STYLE, STYLESHEET, aContent, + CASE_CHECK_AND_REPORT(HASH_STYLE, STYLE, aContent, CSP_UNSAFE_INLINE, STYLE_HASH_VIOLATION_OBSERVER_TOPIC); - CASE_CHECK_AND_REPORT(REQUIRE_SRI_FOR_STYLE, STYLESHEET, NS_LITERAL_STRING(""), + CASE_CHECK_AND_REPORT(REQUIRE_SRI_FOR_STYLE, STYLE, NS_LITERAL_STRING(""), CSP_REQUIRE_SRI_FOR, REQUIRE_SRI_STYLE_VIOLATION_OBSERVER_TOPIC); CASE_CHECK_AND_REPORT(REQUIRE_SRI_FOR_SCRIPT, SCRIPT, NS_LITERAL_STRING(""), CSP_REQUIRE_SRI_FOR, REQUIRE_SRI_SCRIPT_VIOLATION_OBSERVER_TOPIC); diff --git a/dom/security/nsCSPContext.h b/dom/security/nsCSPContext.h index 272e4c733a..85c0615c47 100644 --- a/dom/security/nsCSPContext.h +++ b/dom/security/nsCSPContext.h @@ -133,7 +133,7 @@ class nsCSPContext : public nsIContentSecurityPolicy bool aParserCreated); // helper to report inline script/style violations - void reportInlineViolation(nsContentPolicyType aContentType, + void reportInlineViolation(CSPDirective aDirective, const nsAString& aNonce, const nsAString& aContent, const nsAString& aViolatedDirective, diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp index cb04db315d..aa0f52c4f8 100644 --- a/dom/security/nsCSPUtils.cpp +++ b/dom/security/nsCSPUtils.cpp @@ -1225,16 +1225,6 @@ nsCSPDirective::toDomCSPStruct(mozilla::dom::CSP& outCSP) const } -bool -nsCSPDirective::restrictsContentType(nsContentPolicyType aContentType) const -{ - // make sure we do not check for the default src before any other sources - if (isDefaultDirective()) { - return false; - } - return mDirective == CSP_ContentTypeToDirective(aContentType); -} - void nsCSPDirective::getReportURIs(nsTArray &outReportURIs) const { @@ -1284,19 +1274,6 @@ nsCSPChildSrcDirective::~nsCSPChildSrcDirective() { } -bool nsCSPChildSrcDirective::restrictsContentType(nsContentPolicyType aContentType) const -{ - if (aContentType == nsIContentPolicy::TYPE_SUBDOCUMENT) { - return mRestrictFrames; - } - if (aContentType == nsIContentPolicy::TYPE_INTERNAL_WORKER || - aContentType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER || - aContentType == nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER) { - return mRestrictWorkers; - } - return false; -} - bool nsCSPChildSrcDirective::equals(CSPDirective aDirective) const { if (aDirective == nsIContentSecurityPolicy::FRAME_SRC_DIRECTIVE) { @@ -1320,16 +1297,6 @@ nsCSPScriptSrcDirective::~nsCSPScriptSrcDirective() { } -bool nsCSPScriptSrcDirective::restrictsContentType(nsContentPolicyType aContentType) const -{ - if (aContentType == nsIContentPolicy::TYPE_INTERNAL_WORKER || - aContentType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER || - aContentType == nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER) { - return mRestrictWorkers; - } - return mDirective == CSP_ContentTypeToDirective(aContentType); -} - bool nsCSPScriptSrcDirective::equals(CSPDirective aDirective) const { if (aDirective == nsIContentSecurityPolicy::WORKER_SRC_DIRECTIVE) { @@ -1464,15 +1431,6 @@ nsCSPPolicy::~nsCSPPolicy() } } -bool -nsCSPPolicy::permits(CSPDirective aDir, - nsIURI* aUri, - bool aSpecific) const -{ - nsString outp; - return this->permits(aDir, aUri, EmptyString(), false, aSpecific, false, outp); -} - bool nsCSPPolicy::permits(CSPDirective aDir, nsIURI* aUri, @@ -1526,7 +1484,7 @@ nsCSPPolicy::permits(CSPDirective aDir, } bool -nsCSPPolicy::allows(nsContentPolicyType aContentType, +nsCSPPolicy::allows(CSPDirective aDirective, enum CSPKeyword aKeyword, const nsAString& aHashOrNonce, bool aParserCreated) const @@ -1538,15 +1496,16 @@ nsCSPPolicy::allows(nsContentPolicyType aContentType, // Try to find a matching directive for (uint32_t i = 0; i < mDirectives.Length(); i++) { - if (mDirectives[i]->restrictsContentType(aContentType)) { + if (mDirectives[i]->isDefaultDirective()) { + defaultDir = mDirectives[i]; + continue; + } + if (mDirectives[i]->equals(aDirective)) { if (mDirectives[i]->allows(aKeyword, aHashOrNonce, aParserCreated)) { return true; } return false; } - if (mDirectives[i]->isDefaultDirective()) { - defaultDir = mDirectives[i]; - } } // {nonce,hash}-source should not consult default-src: @@ -1573,13 +1532,6 @@ nsCSPPolicy::allows(nsContentPolicyType aContentType, return true; } -bool -nsCSPPolicy::allows(nsContentPolicyType aContentType, - enum CSPKeyword aKeyword) const -{ - return allows(aContentType, aKeyword, NS_LITERAL_STRING(""), false); -} - void nsCSPPolicy::toString(nsAString& outStr) const { @@ -1634,17 +1586,18 @@ nsCSPPolicy::hasDirective(CSPDirective aDir) const * for the ::permits() function family. */ void -nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType, +nsCSPPolicy::getDirectiveStringForContentType(CSPDirective aDirective, nsAString& outDirective) const { nsCSPDirective* defaultDir = nullptr; for (uint32_t i = 0; i < mDirectives.Length(); i++) { - if (mDirectives[i]->restrictsContentType(aContentType)) { - mDirectives[i]->getDirName(outDirective); - return; - } if (mDirectives[i]->isDefaultDirective()) { defaultDir = mDirectives[i]; + continue; + } + if (mDirectives[i]->equals(aDirective)) { + mDirectives[i]->getDirName(outDirective); + return; } } // if we haven't found a matching directive yet, diff --git a/dom/security/nsCSPUtils.h b/dom/security/nsCSPUtils.h index 9b9ff46c90..51a9a4d7b3 100644 --- a/dom/security/nsCSPUtils.h +++ b/dom/security/nsCSPUtils.h @@ -483,8 +483,6 @@ class nsCSPDirective { virtual void addSrcs(const nsTArray& aSrcs) { mSrcs = aSrcs; } - virtual bool restrictsContentType(nsContentPolicyType aContentType) const; - inline bool isDefaultDirective() const { return mDirective == nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE; } @@ -520,8 +518,6 @@ class nsCSPChildSrcDirective : public nsCSPDirective { void setRestrictWorkers() { mRestrictWorkers = true; } - virtual bool restrictsContentType(nsContentPolicyType aContentType) const; - virtual bool equals(CSPDirective aDirective) const; private: @@ -544,8 +540,6 @@ class nsCSPScriptSrcDirective : public nsCSPDirective { void setRestrictWorkers() { mRestrictWorkers = true; } - virtual bool restrictsContentType(nsContentPolicyType aContentType) const; - virtual bool equals(CSPDirective aDirective) const; private: @@ -668,15 +662,10 @@ class nsCSPPolicy { bool aSpecific, bool aParserCreated, nsAString& outViolatedDirective) const; - bool permits(CSPDirective aDir, - nsIURI* aUri, - bool aSpecific) const; - bool allows(nsContentPolicyType aContentType, + bool allows(CSPDirective aDirective, enum CSPKeyword aKeyword, const nsAString& aHashOrNonce, bool aParserCreated) const; - bool allows(nsContentPolicyType aContentType, - enum CSPKeyword aKeyword) const; void toString(nsAString& outStr) const; void toDomCSPStruct(mozilla::dom::CSP& outCSP) const; @@ -708,7 +697,7 @@ class nsCSPPolicy { void getReportURIs(nsTArray &outReportURIs) const; - void getDirectiveStringForContentType(nsContentPolicyType aContentType, + void getDirectiveStringForContentType(CSPDirective aDirective, nsAString& outDirective) const; void getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const; diff --git a/dom/security/test/unit/test_csp_reports.js b/dom/security/test/unit/test_csp_reports.js index 6c88fb1e10..d5a445750b 100644 --- a/dom/security/test/unit/test_csp_reports.js +++ b/dom/security/test/unit/test_csp_reports.js @@ -215,7 +215,7 @@ function run_test() { function(csp) { var uri = NetUtil // shouldLoad creates and sends out the report here. - csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT, + csp.shouldLoad(Ci.nsIContentSecurityPolicy.SCRIPT_SRC_DIRECTIVE, NetUtil.newURI(selfSpec + "#bar"), null, null, null, null); }); @@ -224,7 +224,7 @@ function run_test() { makeTest(8, {"blocked-uri": "ftp://blocked.test"}, false, function(csp) { // shouldLoad creates and sends out the report here. - csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT, + csp.shouldLoad(Ci.nsIContentSecurityPolicy.SCRIPT_SRC_DIRECTIVE, NetUtil.newURI("ftp://blocked.test/profile.png"), null, null, null, null); }); diff --git a/layout/style/nsStyleUtil.cpp b/layout/style/nsStyleUtil.cpp index 274f5140f2..55329cc6e8 100644 --- a/layout/style/nsStyleUtil.cpp +++ b/layout/style/nsStyleUtil.cpp @@ -774,7 +774,7 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent, } bool allowInlineStyle = true; - rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_STYLESHEET, + rv = csp->GetAllowsInline(nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE, nonce, false, // aParserCreated only applies to scripts aStyleText, aLineNumber, aColumnNumber,