mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1004703 - ignore 'unsafe-inline' if nonce- or hash-source specified (r=sstamm)
This commit is contained in:
parent
774b799f88
commit
07358f5241
@ -29,6 +29,13 @@ couldNotProcessUnknownDirective = Couldn't process unknown directive '%1$S'
|
||||
# LOCALIZATION NOTE (ignoringUnknownOption):
|
||||
# %1$S is the option that could not be understood
|
||||
ignoringUnknownOption = Ignoring unknown option %1$S
|
||||
# LOCALIZATION NOTE (ignoringDuplicateSrc):
|
||||
# %1$S defines the duplicate src
|
||||
ignoringDuplicateSrc = Ignoring duplicate source %1$S
|
||||
# LOCALIZATION NOTE (ignoringSrcWithinScriptSrc):
|
||||
# %1$S is the ignored src
|
||||
# script-src is a directive name and should not be localized
|
||||
ignoringSrcWithinScriptSrc = Ignoring "%1$S" within script-src: nonce-source or hash-source specified
|
||||
# LOCALIZATION NOTE (reportURInotHttpsOrHttp2):
|
||||
# %1$S is the ETLD of the report URI that is not HTTP or HTTPS
|
||||
reportURInotHttpsOrHttp2 = The report URI (%1$S) should be an HTTP or HTTPS URI.
|
||||
|
@ -123,7 +123,9 @@ nsCSPTokenizer::tokenizeCSPPolicy(const nsAString &aPolicyString,
|
||||
nsCSPParser::nsCSPParser(cspTokens& aTokens,
|
||||
nsIURI* aSelfURI,
|
||||
uint64_t aInnerWindowID)
|
||||
: mTokens(aTokens)
|
||||
: mHasHashOrNonce(false)
|
||||
, mUnsafeInlineKeywordSrc(nullptr)
|
||||
, mTokens(aTokens)
|
||||
, mSelfURI(aSelfURI)
|
||||
, mInnerWindowID(aInnerWindowID)
|
||||
{
|
||||
@ -570,8 +572,22 @@ nsCSPParser::keywordSource()
|
||||
return CSP_CreateHostSrcFromURI(mSelfURI);
|
||||
}
|
||||
|
||||
if (CSP_IsKeyword(mCurToken, CSP_UNSAFE_INLINE) ||
|
||||
CSP_IsKeyword(mCurToken, CSP_UNSAFE_EVAL)) {
|
||||
if (CSP_IsKeyword(mCurToken, CSP_UNSAFE_INLINE)) {
|
||||
// make sure script-src only contains 'unsafe-inline' once;
|
||||
// ignore duplicates and log warning
|
||||
if (mUnsafeInlineKeywordSrc) {
|
||||
const char16_t* params[] = { mCurToken.get() };
|
||||
logWarningErrorToConsole(nsIScriptError::warningFlag, "ignoringDuplicateSrc",
|
||||
params, ArrayLength(params));
|
||||
return nullptr;
|
||||
}
|
||||
// cache if we encounter 'unsafe-inline' so we can invalidate (ignore) it in
|
||||
// case that script-src directive also contains hash- or nonce-.
|
||||
mUnsafeInlineKeywordSrc = new nsCSPKeywordSrc(CSP_KeywordToEnum(mCurToken));
|
||||
return mUnsafeInlineKeywordSrc;
|
||||
}
|
||||
|
||||
if (CSP_IsKeyword(mCurToken, CSP_UNSAFE_EVAL)) {
|
||||
return new nsCSPKeywordSrc(CSP_KeywordToEnum(mCurToken));
|
||||
}
|
||||
return nullptr;
|
||||
@ -676,6 +692,8 @@ nsCSPParser::nonceSource()
|
||||
if (dashIndex < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
// cache if encountering hash or nonce to invalidate unsafe-inline
|
||||
mHasHashOrNonce = true;
|
||||
return new nsCSPNonceSrc(Substring(expr,
|
||||
dashIndex + 1,
|
||||
expr.Length() - dashIndex + 1));
|
||||
@ -708,6 +726,8 @@ nsCSPParser::hashSource()
|
||||
|
||||
for (uint32_t i = 0; i < kHashSourceValidFnsLen; i++) {
|
||||
if (algo.LowerCaseEqualsASCII(kHashSourceValidFns[i])) {
|
||||
// cache if encountering hash or nonce to invalidate unsafe-inline
|
||||
mHasHashOrNonce = true;
|
||||
return new nsCSPHashSrc(algo, hash);
|
||||
}
|
||||
}
|
||||
@ -1003,6 +1023,11 @@ nsCSPParser::directive()
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure to reset cache variables when trying to invalidate unsafe-inline;
|
||||
// unsafe-inline might not only appear in script-src, but also in default-src
|
||||
mHasHashOrNonce = false;
|
||||
mUnsafeInlineKeywordSrc = nullptr;
|
||||
|
||||
// Try to parse all the srcs by handing the array off to directiveValue
|
||||
nsTArray<nsCSPBaseSrc*> srcs;
|
||||
directiveValue(srcs);
|
||||
@ -1014,6 +1039,18 @@ nsCSPParser::directive()
|
||||
srcs.AppendElement(keyword);
|
||||
}
|
||||
|
||||
// if a hash or nonce is specified within script-src, then
|
||||
// unsafe-inline should be ignored, see:
|
||||
// http://www.w3.org/TR/CSP2/#directive-script-src
|
||||
if (cspDir->equals(nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE) &&
|
||||
mHasHashOrNonce && mUnsafeInlineKeywordSrc) {
|
||||
mUnsafeInlineKeywordSrc->invalidate();
|
||||
// log to the console that unsafe-inline will be ignored
|
||||
const char16_t* params[] = { NS_LITERAL_STRING("'unsafe-inline'").get() };
|
||||
logWarningErrorToConsole(nsIScriptError::warningFlag, "ignoringSrcWithinScriptSrc",
|
||||
params, ArrayLength(params));
|
||||
}
|
||||
|
||||
// Add the newly created srcs to the directive and add the directive to the policy
|
||||
cspDir->addSrcs(srcs);
|
||||
mPolicy->addDirective(cspDir);
|
||||
|
@ -228,6 +228,10 @@ class nsCSPParser {
|
||||
nsString mCurToken;
|
||||
nsTArray<nsString> mCurDir;
|
||||
|
||||
// cache variables to ignore unsafe-inline if hash or nonce is specified
|
||||
bool mHasHashOrNonce; // false, if no hash or nonce is defined
|
||||
nsCSPKeywordSrc* mUnsafeInlineKeywordSrc; // null, otherwise invlidate()
|
||||
|
||||
cspTokens mTokens;
|
||||
nsIURI* mSelfURI;
|
||||
nsCSPPolicy* mPolicy;
|
||||
|
@ -540,10 +540,11 @@ nsCSPHostSrc::appendPath(const nsAString& aPath)
|
||||
/* ===== nsCSPKeywordSrc ===================== */
|
||||
|
||||
nsCSPKeywordSrc::nsCSPKeywordSrc(enum CSPKeyword aKeyword)
|
||||
: mKeyword(aKeyword)
|
||||
, mInvalidated(false)
|
||||
{
|
||||
NS_ASSERTION((aKeyword != CSP_SELF),
|
||||
"'self' should have been replaced in the parser");
|
||||
mKeyword = aKeyword;
|
||||
}
|
||||
|
||||
nsCSPKeywordSrc::~nsCSPKeywordSrc()
|
||||
@ -553,8 +554,16 @@ nsCSPKeywordSrc::~nsCSPKeywordSrc()
|
||||
bool
|
||||
nsCSPKeywordSrc::allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const
|
||||
{
|
||||
CSPUTILSLOG(("nsCSPKeywordSrc::allows, aKeyWord: %s, a HashOrNonce: %s",
|
||||
CSP_EnumToKeyword(aKeyword), NS_ConvertUTF16toUTF8(aHashOrNonce).get()));
|
||||
CSPUTILSLOG(("nsCSPKeywordSrc::allows, aKeyWord: %s, aHashOrNonce: %s, mInvalidated: %s",
|
||||
CSP_EnumToKeyword(aKeyword),
|
||||
NS_ConvertUTF16toUTF8(aHashOrNonce).get(),
|
||||
mInvalidated ? "yes" : "false"));
|
||||
// if unsafe-inline should be ignored, then bail early
|
||||
if (mInvalidated) {
|
||||
NS_ASSERTION(mKeyword == CSP_UNSAFE_INLINE,
|
||||
"should only invalidate unsafe-inline within script-src");
|
||||
return false;
|
||||
}
|
||||
return mKeyword == aKeyword;
|
||||
}
|
||||
|
||||
@ -564,6 +573,14 @@ nsCSPKeywordSrc::toString(nsAString& outStr) const
|
||||
outStr.AppendASCII(CSP_EnumToKeyword(mKeyword));
|
||||
}
|
||||
|
||||
void
|
||||
nsCSPKeywordSrc::invalidate()
|
||||
{
|
||||
mInvalidated = true;
|
||||
NS_ASSERTION(mInvalidated == CSP_UNSAFE_INLINE,
|
||||
"invalidate 'unsafe-inline' only within script-src");
|
||||
}
|
||||
|
||||
/* ===== nsCSPNonceSrc ==================== */
|
||||
|
||||
nsCSPNonceSrc::nsCSPNonceSrc(const nsAString& aNonce)
|
||||
|
@ -220,9 +220,12 @@ class nsCSPKeywordSrc : public nsCSPBaseSrc {
|
||||
|
||||
bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const;
|
||||
void toString(nsAString& outStr) const;
|
||||
void invalidate();
|
||||
|
||||
private:
|
||||
CSPKeyword mKeyword;
|
||||
// invalidate 'unsafe-inline' if nonce- or hash-source specified
|
||||
bool mInvalidated;
|
||||
};
|
||||
|
||||
/* =============== nsCSPNonceSource =========== */
|
||||
|
Loading…
Reference in New Issue
Block a user