From c3039dadd95f5487e84311a9719604fa901aacd7 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sat, 3 Mar 2018 11:21:43 +0100 Subject: Add support for CSP v3 "worker-src" directive --- dom/security/nsCSPParser.cpp | 47 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) (limited to 'dom/security/nsCSPParser.cpp') diff --git a/dom/security/nsCSPParser.cpp b/dom/security/nsCSPParser.cpp index 86aa4e001..a0eba6918 100644 --- a/dom/security/nsCSPParser.cpp +++ b/dom/security/nsCSPParser.cpp @@ -136,6 +136,8 @@ nsCSPParser::nsCSPParser(cspTokens& aTokens, , mUnsafeInlineKeywordSrc(nullptr) , mChildSrc(nullptr) , mFrameSrc(nullptr) + , mWorkerSrc(nullptr) + , mScriptSrc(nullptr) , mParsingFrameAncestorsDir(false) , mTokens(aTokens) , mSelfURI(aSelfURI) @@ -1099,21 +1101,37 @@ nsCSPParser::directiveName() return new nsUpgradeInsecureDirective(CSP_StringToCSPDirective(mCurToken)); } - // child-src has it's own class to handle frame-src if necessary + // child-src by itself is deprecatd but will be enforced + // * for workers (if worker-src is not explicitly specified) + // * for frames (if frame-src is not explicitly specified) if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::CHILD_SRC_DIRECTIVE)) { + const char16_t* params[] = { mCurToken.get() }; + logWarningErrorToConsole(nsIScriptError::warningFlag, + "deprecatedChildSrcDirective", + params, ArrayLength(params)); mChildSrc = new nsCSPChildSrcDirective(CSP_StringToCSPDirective(mCurToken)); return mChildSrc; } - // if we have a frame-src, cache it so we can decide whether to use child-src + // if we have a frame-src, cache it so we can discard child-src for frames if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::FRAME_SRC_DIRECTIVE)) { - const char16_t* params[] = { mCurToken.get(), NS_LITERAL_STRING("child-src").get() }; - logWarningErrorToConsole(nsIScriptError::warningFlag, "deprecatedDirective", - params, ArrayLength(params)); mFrameSrc = new nsCSPDirective(CSP_StringToCSPDirective(mCurToken)); return mFrameSrc; } + // if we have a worker-src, cache it so we can discard child-src for workers + if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::WORKER_SRC_DIRECTIVE)) { + mWorkerSrc = new nsCSPDirective(CSP_StringToCSPDirective(mCurToken)); + return mWorkerSrc; + } + + // if we have a script-src, cache it as a fallback for worker-src + // in case child-src is not present + if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE)) { + mScriptSrc = new nsCSPScriptSrcDirective(CSP_StringToCSPDirective(mCurToken)); + return mScriptSrc; + } + if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REQUIRE_SRI_FOR)) { return new nsRequireSRIForDirective(CSP_StringToCSPDirective(mCurToken)); } @@ -1290,9 +1308,22 @@ nsCSPParser::policy() directive(); } - if (mChildSrc && !mFrameSrc) { - // if we have a child-src, it handles frame-src too, unless frame-src is set - mChildSrc->setHandleFrameSrc(); + if (mChildSrc) { + if (!mFrameSrc) { + // if frame-src is specified explicitly for that policy than child-src should + // not restrict frames; if not, than child-src needs to restrict frames. + mChildSrc->setRestrictFrames(); + } + if (!mWorkerSrc) { + // if worker-src is specified explicitly for that policy than child-src should + // not restrict workers; if not, than child-src needs to restrict workers. + mChildSrc->setRestrictWorkers(); + } + } + // if script-src is specified, but not worker-src and also no child-src, then + // script-src has to govern workers. + if (mScriptSrc && !mWorkerSrc && !mChildSrc) { + mScriptSrc->setRestrictWorkers(); } return mPolicy; -- cgit v1.2.3