mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 663570 - MetaCSP Part 1: CSP parser changes (r=sicking)
This commit is contained in:
parent
60ea185133
commit
f830e615e5
@ -2615,7 +2615,7 @@ AppendCSPFromHeader(nsIContentSecurityPolicy* csp,
|
||||
nsCharSeparatedTokenizer tokenizer(aHeaderValue, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& policy = tokenizer.nextToken();
|
||||
rv = csp->AppendPolicy(policy, aReportOnly);
|
||||
rv = csp->AppendPolicy(policy, aReportOnly, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
{
|
||||
MOZ_LOG(gCspPRLog, LogLevel::Debug,
|
||||
@ -2768,12 +2768,12 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
|
||||
// ----- if the doc is an app and we want a default CSP, apply it.
|
||||
if (applyAppDefaultCSP) {
|
||||
csp->AppendPolicy(appDefaultCSP, false);
|
||||
csp->AppendPolicy(appDefaultCSP, false, false);
|
||||
}
|
||||
|
||||
// ----- if the doc is an app and specifies a CSP in its manifest, apply it.
|
||||
if (applyAppManifestCSP) {
|
||||
csp->AppendPolicy(appManifestCSP, false);
|
||||
csp->AppendPolicy(appManifestCSP, false, false);
|
||||
}
|
||||
|
||||
// ----- if the doc is part of Loop, apply the loop CSP
|
||||
@ -2783,7 +2783,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
NS_ASSERTION(loopCSP, "Missing loop.CSP preference");
|
||||
// If the pref has been removed, we continue without setting a CSP
|
||||
if (loopCSP) {
|
||||
csp->AppendPolicy(loopCSP, false);
|
||||
csp->AppendPolicy(loopCSP, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ interface nsIURI;
|
||||
|
||||
typedef unsigned short CSPDirective;
|
||||
|
||||
[scriptable, builtinclass, uuid(b9a029c3-9484-4bf7-826d-0c6b545790bc)]
|
||||
[scriptable, builtinclass, uuid(b3c4c0ae-bd5e-4cad-87e0-8d210dbb3f9f)]
|
||||
interface nsIContentSecurityPolicy : nsISerializable
|
||||
{
|
||||
/**
|
||||
@ -90,12 +90,17 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||
/**
|
||||
* Parse and install a CSP policy.
|
||||
* @param aPolicy
|
||||
* String representation of the policy (e.g., header value)
|
||||
* String representation of the policy
|
||||
* (e.g., header value, meta content)
|
||||
* @param reportOnly
|
||||
* Should this policy affect content, script and style processing or
|
||||
* just send reports if it is violated?
|
||||
* @param deliveredViaMetaTag
|
||||
* Indicates whether the policy was delivered via the meta tag.
|
||||
*/
|
||||
void appendPolicy(in AString policyString, in boolean reportOnly);
|
||||
void appendPolicy(in AString policyString,
|
||||
in boolean reportOnly,
|
||||
in boolean deliveredViaMetaTag);
|
||||
|
||||
/*
|
||||
* Whether this policy allows inline script or style.
|
||||
|
@ -32,6 +32,9 @@ ignoringUnknownOption = Ignoring unknown option %1$S
|
||||
# LOCALIZATION NOTE (ignoringDuplicateSrc):
|
||||
# %1$S defines the duplicate src
|
||||
ignoringDuplicateSrc = Ignoring duplicate source %1$S
|
||||
# LOCALIZATION NOTE (ignoringSrcFromMetaCSP):
|
||||
# %1$S defines the ignored src
|
||||
ignoringSrcFromMetaCSP = Ignoring source '%1$S' (Not supported when delivered via meta element).
|
||||
# LOCALIZATION NOTE (ignoringSrcWithinScriptSrc):
|
||||
# %1$S is the ignored src
|
||||
# script-src is a directive name and should not be localized
|
||||
|
@ -342,14 +342,17 @@ nsCSPContext::GetReferrerPolicy(uint32_t* outPolicy, bool* outIsSet)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::AppendPolicy(const nsAString& aPolicyString,
|
||||
bool aReportOnly)
|
||||
bool aReportOnly,
|
||||
bool aDeliveredViaMetaTag)
|
||||
{
|
||||
CSPCONTEXTLOG(("nsCSPContext::AppendPolicy: %s",
|
||||
NS_ConvertUTF16toUTF8(aPolicyString).get()));
|
||||
|
||||
// Use the mSelfURI from setRequestContext, see bug 991474
|
||||
NS_ASSERTION(mSelfURI, "mSelfURI required for AppendPolicy, but not set");
|
||||
nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy(aPolicyString, mSelfURI, aReportOnly, this);
|
||||
nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy(aPolicyString, mSelfURI,
|
||||
aReportOnly, this,
|
||||
aDeliveredViaMetaTag);
|
||||
if (policy) {
|
||||
mPolicies.AppendElement(policy);
|
||||
// reset cache since effective policy changes
|
||||
@ -1353,10 +1356,15 @@ nsCSPContext::Read(nsIObjectInputStream* aStream)
|
||||
rv = aStream->ReadBoolean(&reportOnly);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// @param deliveredViaMetaTag:
|
||||
// when parsing the CSP policy string initially we already remove directives
|
||||
// that should not be processed when delivered via the meta tag. Such directives
|
||||
// will not be present at this point anymore.
|
||||
nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy(policyString,
|
||||
mSelfURI,
|
||||
reportOnly,
|
||||
this);
|
||||
this,
|
||||
false);
|
||||
if (policy) {
|
||||
mPolicies.AppendElement(policy);
|
||||
}
|
||||
|
@ -122,7 +122,8 @@ nsCSPTokenizer::tokenizeCSPPolicy(const nsAString &aPolicyString,
|
||||
|
||||
nsCSPParser::nsCSPParser(cspTokens& aTokens,
|
||||
nsIURI* aSelfURI,
|
||||
nsCSPContext* aCSPContext)
|
||||
nsCSPContext* aCSPContext,
|
||||
bool aDeliveredViaMetaTag)
|
||||
: mHasHashOrNonce(false)
|
||||
, mUnsafeInlineKeywordSrc(nullptr)
|
||||
, mChildSrc(nullptr)
|
||||
@ -130,6 +131,7 @@ nsCSPParser::nsCSPParser(cspTokens& aTokens,
|
||||
, mTokens(aTokens)
|
||||
, mSelfURI(aSelfURI)
|
||||
, mCSPContext(aCSPContext)
|
||||
, mDeliveredViaMetaTag(aDeliveredViaMetaTag)
|
||||
{
|
||||
CSPPARSERLOG(("nsCSPParser::nsCSPParser"));
|
||||
}
|
||||
@ -991,6 +993,20 @@ nsCSPParser::directiveName()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// CSP delivered via meta tag should ignore the following directives:
|
||||
// report-uri, frame-ancestors, and sandbox, see:
|
||||
// http://www.w3.org/TR/CSP11/#delivery-html-meta-element
|
||||
if (mDeliveredViaMetaTag &&
|
||||
((CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REPORT_URI_DIRECTIVE)) ||
|
||||
(CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE)))) {
|
||||
// log to the console to indicate that meta CSP is ignoring the directive
|
||||
const char16_t* params[] = { mCurToken.get() };
|
||||
logWarningErrorToConsole(nsIScriptError::warningFlag,
|
||||
"ignoringSrcFromMetaCSP",
|
||||
params, ArrayLength(params));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// special case handling for upgrade-insecure-requests
|
||||
if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE)) {
|
||||
return new nsUpgradeInsecureDirective(CSP_StringToCSPDirective(mCurToken));
|
||||
@ -1116,7 +1132,8 @@ nsCSPPolicy*
|
||||
nsCSPParser::parseContentSecurityPolicy(const nsAString& aPolicyString,
|
||||
nsIURI *aSelfURI,
|
||||
bool aReportOnly,
|
||||
nsCSPContext* aCSPContext)
|
||||
nsCSPContext* aCSPContext,
|
||||
bool aDeliveredViaMetaTag)
|
||||
{
|
||||
if (CSPPARSERLOGENABLED()) {
|
||||
CSPPARSERLOG(("nsCSPParser::parseContentSecurityPolicy, policy: %s",
|
||||
@ -1126,6 +1143,8 @@ nsCSPParser::parseContentSecurityPolicy(const nsAString& aPolicyString,
|
||||
CSPPARSERLOG(("nsCSPParser::parseContentSecurityPolicy, selfURI: %s", spec.get()));
|
||||
CSPPARSERLOG(("nsCSPParser::parseContentSecurityPolicy, reportOnly: %s",
|
||||
(aReportOnly ? "true" : "false")));
|
||||
CSPPARSERLOG(("nsCSPParser::parseContentSecurityPolicy, deliveredViaMetaTag: %s",
|
||||
(aDeliveredViaMetaTag ? "true" : "false")));
|
||||
}
|
||||
|
||||
NS_ASSERTION(aSelfURI, "Can not parseContentSecurityPolicy without aSelfURI");
|
||||
@ -1138,7 +1157,7 @@ nsCSPParser::parseContentSecurityPolicy(const nsAString& aPolicyString,
|
||||
nsTArray< nsTArray<nsString> > tokens;
|
||||
nsCSPTokenizer::tokenizeCSPPolicy(aPolicyString, tokens);
|
||||
|
||||
nsCSPParser parser(tokens, aSelfURI, aCSPContext);
|
||||
nsCSPParser parser(tokens, aSelfURI, aCSPContext, aDeliveredViaMetaTag);
|
||||
|
||||
// Start the parser to generate a new CSPPolicy using the generated tokens.
|
||||
nsCSPPolicy* policy = parser.policy();
|
||||
|
@ -100,12 +100,15 @@ class nsCSPParser {
|
||||
static nsCSPPolicy* parseContentSecurityPolicy(const nsAString &aPolicyString,
|
||||
nsIURI *aSelfURI,
|
||||
bool aReportOnly,
|
||||
nsCSPContext* aCSPContext);
|
||||
nsCSPContext* aCSPContext,
|
||||
bool aDeliveredViaMetaTag);
|
||||
|
||||
private:
|
||||
nsCSPParser(cspTokens& aTokens,
|
||||
nsIURI* aSelfURI,
|
||||
nsCSPContext* aCSPContext);
|
||||
nsCSPContext* aCSPContext,
|
||||
bool aDeliveredViaMetaTag);
|
||||
|
||||
~nsCSPParser();
|
||||
|
||||
|
||||
@ -246,6 +249,7 @@ class nsCSPParser {
|
||||
nsIURI* mSelfURI;
|
||||
nsCSPPolicy* mPolicy;
|
||||
nsCSPContext* mCSPContext; // used for console logging
|
||||
bool mDeliveredViaMetaTag;
|
||||
};
|
||||
|
||||
#endif /* nsCSPParser_h___ */
|
||||
|
@ -117,7 +117,7 @@ nsresult runTest(uint32_t aExpectedPolicyCount, // this should be 0 for policies
|
||||
// append a policy
|
||||
nsString policyStr;
|
||||
policyStr.AssignASCII(aPolicy);
|
||||
rv = csp->AppendPolicy(policyStr, false);
|
||||
rv = csp->AppendPolicy(policyStr, false, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// when executing fuzzy tests we do not care about the actual output
|
||||
|
@ -84,7 +84,7 @@ function makeTest(id, expectedJSON, useReportOnlyPolicy, callback) {
|
||||
|
||||
// Load up the policy
|
||||
// set as report-only if that's the case
|
||||
csp.appendPolicy(policy, useReportOnlyPolicy);
|
||||
csp.appendPolicy(policy, useReportOnlyPolicy, false);
|
||||
|
||||
// prime the report server
|
||||
var handler = makeReportHandler("/test" + id, "Test " + id, expectedJSON);
|
||||
|
Loading…
Reference in New Issue
Block a user