Issue #2466 - Part 3: Implement style-src-elem and style-src-attr

This commit is contained in:
Moonchild 2024-02-04 23:24:50 +01:00 committed by roytam1
commit 721ded9b48
8 changed files with 78 additions and 12 deletions

View file

@ -62,6 +62,8 @@ interface nsIContentSecurityPolicy : nsISerializable
const unsigned short WORKER_SRC_DIRECTIVE = 22;
const unsigned short SCRIPT_SRC_ELEM_DIRECTIVE = 23;
const unsigned short SCRIPT_SRC_ATTR_DIRECTIVE = 24;
const unsigned short STYLE_SRC_ELEM_DIRECTIVE = 25;
const unsigned short STYLE_SRC_ATTR_DIRECTIVE = 26;
/**
* Accessor method for a read-only string version of the policy at a given

View file

@ -569,9 +569,9 @@ nsCSPContext::GetAllowsInline(CSPDirective aDirective,
if (aDirective != SCRIPT_SRC_ELEM_DIRECTIVE &&
aDirective != SCRIPT_SRC_ATTR_DIRECTIVE &&
aDirective != STYLE_SRC_DIRECTIVE) {
MOZ_ASSERT(false,
"can only allow inline for script-src-(attr/elem) or style");
aDirective != STYLE_SRC_ELEM_DIRECTIVE &&
aDirective != STYLE_SRC_ATTR_DIRECTIVE) {
MOZ_ASSERT(false, "can only allow inline for (script/style)-src-(attr/elem) or style");
return NS_OK;
}

View file

@ -115,6 +115,7 @@ nsCSPParser::nsCSPParser(cspTokens& aTokens,
, mFrameSrc(nullptr)
, mWorkerSrc(nullptr)
, mScriptSrc(nullptr)
, mStyleSrc(nullptr)
, mParsingFrameAncestorsDir(false)
, mTokens(aTokens)
, mSelfURI(aSelfURI)
@ -1087,6 +1088,13 @@ nsCSPParser::directiveName()
mScriptSrc = new nsCSPScriptSrcDirective(CSP_StringToCSPDirective(mCurToken));
return mScriptSrc;
}
// If we have a style-src, cache it as a fallback for style-src-elem and
// style-src-attr.
if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE)) {
mStyleSrc = new nsCSPStyleSrcDirective(CSP_StringToCSPDirective(mCurToken));
return mStyleSrc;
}
if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REQUIRE_SRI_FOR)) {
return new nsRequireSRIForDirective(CSP_StringToCSPDirective(mCurToken));
@ -1314,6 +1322,18 @@ nsCSPParser::policy()
mScriptSrc->setRestrictScriptAttr();
}
// If style-src is specified and style-src-elem is not specified, then
// style-src serves as a fallback.
if (mStyleSrc && !mPolicy->hasDirective(nsIContentSecurityPolicy::STYLE_SRC_ELEM_DIRECTIVE)) {
mStyleSrc->setRestrictStyleElem();
}
// If style-src is specified and style-src-attr is not specified, then
// style-src serves as a fallback.
if (mStyleSrc && !mPolicy->hasDirective(nsIContentSecurityPolicy::STYLE_SRC_ATTR_DIRECTIVE)) {
mStyleSrc->setRestrictStyleAttr();
}
return mPolicy;
}

View file

@ -255,6 +255,7 @@ class nsCSPParser {
nsCSPDirective* mFrameSrc;
nsCSPDirective* mWorkerSrc;
nsCSPScriptSrcDirective* mScriptSrc;
nsCSPStyleSrcDirective* mStyleSrc;
// cache variable to let nsCSPHostSrc know that it's within
// the frame-ancestors directive.

View file

@ -224,7 +224,7 @@ CSP_ContentTypeToDirective(nsContentPolicyType aType)
return nsIContentSecurityPolicy::SCRIPT_SRC_ELEM_DIRECTIVE;
case nsIContentPolicy::TYPE_STYLESHEET:
return nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE;
return nsIContentSecurityPolicy::STYLE_SRC_ELEM_DIRECTIVE;
case nsIContentPolicy::TYPE_FONT:
return nsIContentSecurityPolicy::FONT_SRC_DIRECTIVE;
@ -1313,12 +1313,9 @@ nsCSPScriptSrcDirective::nsCSPScriptSrcDirective(CSPDirective aDirective)
{
}
nsCSPScriptSrcDirective::~nsCSPScriptSrcDirective()
{
}
nsCSPScriptSrcDirective::~nsCSPScriptSrcDirective() = default;
bool nsCSPScriptSrcDirective::equals(CSPDirective aDirective) const
{
bool nsCSPScriptSrcDirective::equals(CSPDirective aDirective) const {
if (aDirective == nsIContentSecurityPolicy::WORKER_SRC_DIRECTIVE) {
return mRestrictWorkers;
}
@ -1331,6 +1328,27 @@ bool nsCSPScriptSrcDirective::equals(CSPDirective aDirective) const
return (mDirective == aDirective);
}
/* =============== nsCSPStyleSrcDirective ============= */
nsCSPStyleSrcDirective::nsCSPStyleSrcDirective(CSPDirective aDirective)
: nsCSPDirective(aDirective)
, mRestrictStyleElem(false)
, mRestrictStyleAttr(false)
{
}
nsCSPStyleSrcDirective::~nsCSPStyleSrcDirective() = default;
bool nsCSPStyleSrcDirective::equals(CSPDirective aDirective) const {
if (aDirective == nsIContentSecurityPolicy::STYLE_SRC_ELEM_DIRECTIVE) {
return mRestrictStyleElem;
}
if (aDirective == nsIContentSecurityPolicy::STYLE_SRC_ATTR_DIRECTIVE) {
return mRestrictStyleAttr;
}
return (mDirective == aDirective);
}
/* =============== nsBlockAllMixedContentDirective ============= */
nsBlockAllMixedContentDirective::nsBlockAllMixedContentDirective(CSPDirective aDirective)

View file

@ -143,7 +143,9 @@ static const char* CSPStrDirectives[] = {
"sandbox", // SANDBOX_DIRECTIVE
"worker-src", // WORKER_SRC_DIRECTIVE
"script-src-elem", // SCRIPT_SRC_ELEM_DIRECTIVE
"script-src-attr" // SCRIPT_SRC_ATTR_DIRECTIVE
"script-src-attr", // SCRIPT_SRC_ATTR_DIRECTIVE
"style-src-elem", // STYLE_SRC_ELEM_DIRECTIVE
"style-src-attr" // STYLE_SRC_ATTR_DIRECTIVE
};
inline const char* CSP_CSPDirectiveToString(CSPDirective aDir)
@ -551,6 +553,27 @@ class nsCSPScriptSrcDirective : public nsCSPDirective {
bool mRestrictScriptAttr;
};
/* =============== nsCSPStyleSrcDirective ============= */
/*
* In CSP 3, style-src is used as a fallback for style-src-elem and
* style-src-attr in case they aren't defined.
*/
class nsCSPStyleSrcDirective : public nsCSPDirective {
public:
explicit nsCSPStyleSrcDirective(CSPDirective aDirective);
virtual ~nsCSPStyleSrcDirective();
void setRestrictStyleElem() { mRestrictStyleElem = true; }
void setRestrictStyleAttr() { mRestrictStyleAttr = true; }
virtual bool equals(CSPDirective aDirective) const;
private:
bool mRestrictStyleElem;
bool mRestrictStyleAttr;
};
/* =============== nsBlockAllMixedContentDirective === */
class nsBlockAllMixedContentDirective : public nsCSPDirective {

View file

@ -50,7 +50,7 @@ function checkResults(reportStr) {
"http://mochi.test:8888/tests/dom/security/test/csp/test_report_for_import.html",
"Incorrect referrer");
is(cspReport["violated-directive"],
"style-src http://mochi.test:8888",
"style-src-elem http://mochi.test:8888",
"Incorrect violated-directive");
is(cspReport["original-policy"],
"style-src http://mochi.test:8888; report-uri " +

View file

@ -767,14 +767,16 @@ nsStyleUtil::CSPAllowsInlineStyle(nsIContent* aContent,
return true;
}
CSPDirective directive = nsIContentSecurityPolicy::STYLE_SRC_ATTR_DIRECTIVE;
// query the nonce
nsAutoString nonce;
if (aContent) {
directive = nsIContentSecurityPolicy::STYLE_SRC_ELEM_DIRECTIVE;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::nonce, nonce);
}
bool allowInlineStyle = true;
rv = csp->GetAllowsInline(nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE,
rv = csp->GetAllowsInline(directive,
nonce,
false, // aParserCreated only applies to scripts
aStyleText, aLineNumber, aColumnNumber,