Backed out 4 changesets (bug 1683464) for multiple perma failures. CLOSED TREE

Backed out changeset a5d315c017d0 (bug 1683464)
Backed out changeset 5f91001e4923 (bug 1683464)
Backed out changeset 1b7fe904e8af (bug 1683464)
Backed out changeset eb1c479fddca (bug 1683464)
This commit is contained in:
Razvan Maries 2021-01-05 16:47:22 +02:00
Родитель 1366657475
Коммит 6a4eb25b10
13 изменённых файлов: 225 добавлений и 119 удалений

Просмотреть файл

@ -1368,6 +1368,18 @@ class nsContentUtils {
static inline nsContentPolicyType
InternalContentPolicyTypeToExternalOrPreload(nsContentPolicyType aType);
/**
* Map internal content policy types to external ones, worker, or preload
* types:
* * TYPE_INTERNAL_WORKER
* * TYPE_INTERNAL_SHARED_WORKER
* * TYPE_INTERNAL_SERVICE_WORKER
*
* Note: DO NOT call this function unless you know what you're doing!
*/
static nsContentPolicyType InternalContentPolicyTypeToExternalOrWorker(
nsContentPolicyType aType);
/**
* Returns true if the content policy type is any of:
* * TYPE_INTERNAL_SCRIPT_PRELOAD
@ -3483,6 +3495,20 @@ nsContentUtils::InternalContentPolicyTypeToExternal(nsContentPolicyType aType) {
}
}
/* static */ inline nsContentPolicyType
nsContentUtils::InternalContentPolicyTypeToExternalOrWorker(
nsContentPolicyType aType) {
switch (aType) {
case nsIContentPolicy::TYPE_INTERNAL_WORKER:
case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
return aType;
default:
return InternalContentPolicyTypeToExternal(aType);
}
}
class MOZ_RAII nsAutoScriptBlocker {
public:
explicit nsAutoScriptBlocker() { nsContentUtils::AddScriptBlocker(); }

Просмотреть файл

@ -829,7 +829,7 @@ nsresult EventListenerManager::SetEventHandler(nsAtom* aName,
if (csp) {
bool allowsInlineScript = true;
rv = csp->GetAllowsInline(
nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE,
nsIContentPolicy::TYPE_SCRIPT,
u""_ns, // aNonce
true, // aParserCreated (true because attribute event handler)
aElement,

Просмотреть файл

@ -137,7 +137,7 @@ interface nsIContentSecurityPolicy : nsISerializable
* Whether or not the effects of the inline style should be allowed
* (block the rules if false).
*/
boolean getAllowsInline(in nsIContentSecurityPolicy_CSPDirective aDirective,
boolean getAllowsInline(in nsContentPolicyType aContentPolicyType,
in AString aNonce,
in boolean aParserCreated,
in Element aTriggeringElement,

Просмотреть файл

@ -137,16 +137,15 @@ static bool AllowedByCSP(nsIContentSecurityPolicy* aCSP,
}
bool allowsInlineScript = true;
nsresult rv =
aCSP->GetAllowsInline(nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE,
u""_ns, // aNonce
true, // aParserCreated
nullptr, // aElement,
nullptr, // nsICSPEventListener
aContentOfPseudoScript, // aContent
0, // aLineNumber
0, // aColumnNumber
&allowsInlineScript);
nsresult rv = aCSP->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT,
u""_ns, // aNonce
true, // aParserCreated
nullptr, // aElement,
nullptr, // nsICSPEventListener
aContentOfPseudoScript, // aContent
0, // aLineNumber
0, // aColumnNumber
&allowsInlineScript);
return (NS_SUCCEEDED(rv) && allowsInlineScript);
}

Просмотреть файл

@ -1643,11 +1643,11 @@ static bool CSPAllowsInlineScript(nsIScriptElement* aElement,
aElement->GetParserCreated() != mozilla::dom::NOT_FROM_PARSER;
bool allowInlineScript = false;
rv = csp->GetAllowsInline(
nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE, nonce, parserCreated,
scriptContent, nullptr /* nsICSPEventListener */, u""_ns,
aElement->GetScriptLineNumber(), aElement->GetScriptColumnNumber(),
&allowInlineScript);
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_SCRIPT, nonce, parserCreated,
scriptContent, nullptr /* nsICSPEventListener */,
u""_ns, aElement->GetScriptLineNumber(),
aElement->GetScriptColumnNumber(),
&allowInlineScript);
return NS_SUCCEEDED(rv) && allowInlineScript;
}

Просмотреть файл

@ -127,6 +127,15 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
CSPCONTEXTLOG((">>>> aContentType: %d", aContentType));
}
bool isPreload = nsContentUtils::IsPreloadType(aContentType);
// Since we know whether we are dealing with a preload, we have to convert
// the internal policytype ot the external policy type before moving on.
// We still need to know if this is a worker so child-src can handle that
// case correctly.
aContentType =
nsContentUtils::InternalContentPolicyTypeToExternalOrWorker(aContentType);
// This ShouldLoad function is called from nsCSPService::ShouldLoad,
// which already checked a number of things, including:
// * aContentLocation is not null; we can consume this without further checks
@ -145,14 +154,15 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
return NS_OK;
}
bool permitted = permitsInternal(
dir,
nullptr, // aTriggeringElement
aCSPEventListener, aContentLocation, aOriginalURIIfRedirect, aNonce,
false, // allow fallback to default-src
aSendViolationReports,
true, // send blocked URI in violation reports
aParserCreated);
bool permitted =
permitsInternal(dir,
nullptr, // aTriggeringElement
aCSPEventListener, aContentLocation,
aOriginalURIIfRedirect, aNonce, isPreload,
false, // allow fallback to default-src
aSendViolationReports,
true, // send blocked URI in violation reports
aParserCreated);
*outDecision =
permitted ? nsIContentPolicy::ACCEPT : nsIContentPolicy::REJECT_SERVER;
@ -170,9 +180,9 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
bool nsCSPContext::permitsInternal(
CSPDirective aDir, Element* aTriggeringElement,
nsICSPEventListener* aCSPEventListener, nsIURI* aContentLocation,
nsIURI* aOriginalURIIfRedirect, const nsAString& aNonce, bool aSpecific,
bool aSendViolationReports, bool aSendContentLocationInViolationReports,
bool aParserCreated) {
nsIURI* aOriginalURIIfRedirect, const nsAString& aNonce, bool aIsPreload,
bool aSpecific, bool aSendViolationReports,
bool aSendContentLocationInViolationReports, bool aParserCreated) {
EnsureIPCPoliciesRead();
bool permits = true;
@ -188,10 +198,10 @@ bool nsCSPContext::permitsInternal(
permits = false;
}
// Callers should set |aSendViolationReports| to false if this is a
// preload - the decision may be wrong due to the inability to get the
// nonce, and will incorrectly fail the unit tests.
if (aSendViolationReports) {
// Do not send a report or notify observers if this is a preload - the
// decision may be wrong due to the inability to get the nonce, and will
// incorrectly fail the unit tests.
if (!aIsPreload && aSendViolationReports) {
uint32_t lineNumber = 0;
uint32_t columnNumber = 0;
nsAutoString spec;
@ -438,8 +448,8 @@ nsCSPContext::GetAllowsEval(bool* outShouldReportViolation,
*outAllowsEval = true;
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
if (!mPolicies[i]->allows(SCRIPT_SRC_DIRECTIVE, CSP_UNSAFE_EVAL, u""_ns,
false)) {
if (!mPolicies[i]->allows(nsIContentPolicy::TYPE_SCRIPT, CSP_UNSAFE_EVAL,
u""_ns, false)) {
// policy is violated: must report the violation and allow the inline
// script if the policy is report-only.
*outShouldReportViolation = true;
@ -453,7 +463,7 @@ nsCSPContext::GetAllowsEval(bool* outShouldReportViolation,
// Helper function to report inline violations
void nsCSPContext::reportInlineViolation(
CSPDirective aDirective, Element* aTriggeringElement,
nsContentPolicyType aContentType, Element* aTriggeringElement,
nsICSPEventListener* aCSPEventListener, const nsAString& aNonce,
const nsAString& aContent, const nsAString& aViolatedDirective,
uint32_t aViolatedPolicyIndex, // TODO, use report only flag for that
@ -463,13 +473,13 @@ void nsCSPContext::reportInlineViolation(
// let's report the hash error; no need to report the unsafe-inline error
// anymore.
if (!aNonce.IsEmpty()) {
observerSubject = (aDirective == SCRIPT_SRC_DIRECTIVE)
observerSubject = (aContentType == nsIContentPolicy::TYPE_SCRIPT)
? NS_LITERAL_STRING_FROM_CSTRING(
SCRIPT_NONCE_VIOLATION_OBSERVER_TOPIC)
: NS_LITERAL_STRING_FROM_CSTRING(
STYLE_NONCE_VIOLATION_OBSERVER_TOPIC);
} else {
observerSubject = (aDirective == SCRIPT_SRC_DIRECTIVE)
observerSubject = (aContentType == nsIContentPolicy::TYPE_SCRIPT)
? NS_LITERAL_STRING_FROM_CSTRING(
SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC)
: NS_LITERAL_STRING_FROM_CSTRING(
@ -507,15 +517,22 @@ void nsCSPContext::reportInlineViolation(
}
NS_IMETHODIMP
nsCSPContext::GetAllowsInline(CSPDirective aDirective, const nsAString& aNonce,
bool aParserCreated, Element* aTriggeringElement,
nsCSPContext::GetAllowsInline(nsContentPolicyType aContentType,
const nsAString& aNonce, bool aParserCreated,
Element* aTriggeringElement,
nsICSPEventListener* aCSPEventListener,
const nsAString& aContentOfPseudoScript,
uint32_t aLineNumber, uint32_t aColumnNumber,
bool* outAllowsInline) {
*outAllowsInline = true;
if (aDirective != SCRIPT_SRC_DIRECTIVE && aDirective != STYLE_SRC_DIRECTIVE) {
MOZ_ASSERT(
aContentType ==
nsContentUtils::InternalContentPolicyTypeToExternal(aContentType),
"We should only see external content policy types here.");
if (aContentType != nsIContentPolicy::TYPE_SCRIPT &&
aContentType != nsIContentPolicy::TYPE_STYLESHEET) {
MOZ_ASSERT(false, "can only allow inline for script or style");
return NS_OK;
}
@ -526,9 +543,9 @@ nsCSPContext::GetAllowsInline(CSPDirective aDirective, const nsAString& aNonce,
// 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(aDirective, CSP_UNSAFE_INLINE, u""_ns,
mPolicies[i]->allows(aContentType, CSP_UNSAFE_INLINE, u""_ns,
aParserCreated) ||
mPolicies[i]->allows(aDirective, CSP_NONCE, aNonce, aParserCreated);
mPolicies[i]->allows(aContentType, 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 so we can avoid allocating
@ -552,7 +569,7 @@ nsCSPContext::GetAllowsInline(CSPDirective aDirective, const nsAString& aNonce,
content = aContentOfPseudoScript;
}
allowed =
mPolicies[i]->allows(aDirective, CSP_HASH, content, aParserCreated);
mPolicies[i]->allows(aContentType, CSP_HASH, content, aParserCreated);
if (!allowed) {
// policy is violoated: deny the load unless policy is report only and
@ -563,8 +580,8 @@ nsCSPContext::GetAllowsInline(CSPDirective aDirective, const nsAString& aNonce,
nsAutoString violatedDirective;
bool reportSample = false;
mPolicies[i]->getDirectiveStringAndReportSampleForContentType(
aDirective, violatedDirective, &reportSample);
reportInlineViolation(aDirective, aTriggeringElement, aCSPEventListener,
aContentType, violatedDirective, &reportSample);
reportInlineViolation(aContentType, aTriggeringElement, aCSPEventListener,
aNonce, reportSample ? content : EmptyString(),
violatedDirective, i, aLineNumber, aColumnNumber);
}
@ -687,18 +704,17 @@ nsCSPContext::GetAllowsNavigateTo(nsIURI* aURI, bool aIsFormSubmission,
* GetAllowsInline() and do not call this macro, hence we can pass 'false'
* as the argument _aParserCreated_ to allows().
*/
#define CASE_CHECK_AND_REPORT(violationType, directive, nonceOrHash, keyword, \
observerTopic) \
#define CASE_CHECK_AND_REPORT(violationType, contentPolicyType, nonceOrHash, \
keyword, observerTopic) \
case nsIContentSecurityPolicy::VIOLATION_TYPE_##violationType: \
PR_BEGIN_MACRO \
static_assert(directive##_SRC_DIRECTIVE == SCRIPT_SRC_DIRECTIVE || \
directive##_SRC_DIRECTIVE == STYLE_SRC_DIRECTIVE); \
if (!mPolicies[p]->allows(directive##_SRC_DIRECTIVE, keyword, nonceOrHash, \
false)) { \
if (!mPolicies[p]->allows(nsIContentPolicy::TYPE_##contentPolicyType, \
keyword, nonceOrHash, false)) { \
nsAutoString violatedDirective; \
bool reportSample = false; \
mPolicies[p]->getDirectiveStringAndReportSampleForContentType( \
directive##_SRC_DIRECTIVE, violatedDirective, &reportSample); \
nsIContentPolicy::TYPE_##contentPolicyType, violatedDirective, \
&reportSample); \
AsyncReportViolation(aTriggeringElement, aCSPEventListener, nullptr, \
blockedContentSource, nullptr, violatedDirective, \
p, NS_LITERAL_STRING_FROM_CSTRING(observerTopic), \
@ -759,17 +775,17 @@ nsCSPContext::LogViolationDetails(
switch (aViolationType) {
CASE_CHECK_AND_REPORT(EVAL, SCRIPT, u""_ns, CSP_UNSAFE_EVAL,
EVAL_VIOLATION_OBSERVER_TOPIC);
CASE_CHECK_AND_REPORT(INLINE_STYLE, STYLE, u""_ns, CSP_UNSAFE_INLINE,
CASE_CHECK_AND_REPORT(INLINE_STYLE, STYLESHEET, u""_ns, CSP_UNSAFE_INLINE,
INLINE_STYLE_VIOLATION_OBSERVER_TOPIC);
CASE_CHECK_AND_REPORT(INLINE_SCRIPT, SCRIPT, u""_ns, 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, STYLE, aNonce, CSP_UNSAFE_INLINE,
CASE_CHECK_AND_REPORT(NONCE_STYLE, STYLESHEET, 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, STYLE, aContent, CSP_UNSAFE_INLINE,
CASE_CHECK_AND_REPORT(HASH_STYLE, STYLESHEET, aContent, CSP_UNSAFE_INLINE,
STYLE_HASH_VIOLATION_OBSERVER_TOPIC);
default:
@ -1602,6 +1618,7 @@ nsCSPContext::PermitsAncestry(nsILoadInfo* aLoadInfo,
ancestorsArray[a],
nullptr, // no redirect here.
u""_ns, // no nonce
false, // not a preload.
true, // specific, do not use default-src
true, // send violation reports
okToSendAncestor,
@ -1638,6 +1655,7 @@ nsCSPContext::Permits(Element* aTriggeringElement,
permitsInternal(aDir, aTriggeringElement, aCSPEventListener, aURI,
nullptr, // no original (pre-redirect) URI
u""_ns, // no nonce
false, // not a preload.
aSpecific,
true, // send violation reports
true, // send blocked URI in violation reports

Просмотреть файл

@ -149,13 +149,13 @@ class nsCSPContext : public nsIContentSecurityPolicy {
mozilla::dom::Element* aTriggeringElement,
nsICSPEventListener* aCSPEventListener,
nsIURI* aContentLocation, nsIURI* aOriginalURIIfRedirect,
const nsAString& aNonce, bool aSpecific,
const nsAString& aNonce, bool aIsPreload, bool aSpecific,
bool aSendViolationReports,
bool aSendContentLocationInViolationReports,
bool aParserCreated);
// helper to report inline script/style violations
void reportInlineViolation(CSPDirective aDirective,
void reportInlineViolation(nsContentPolicyType aContentType,
mozilla::dom::Element* aTriggeringElement,
nsICSPEventListener* aCSPEventListener,
const nsAString& aNonce, const nsAString& aContent,

Просмотреть файл

@ -826,8 +826,7 @@ nsCSPDirective* nsCSPParser::directiveName() {
NS_ConvertUTF16toUTF8(mCurValue).get()));
// Check if it is a valid directive
CSPDirective directive = CSP_StringToCSPDirective(mCurToken);
if (directive == nsIContentSecurityPolicy::NO_DIRECTIVE) {
if (!CSP_IsValidDirective(mCurToken)) {
AutoTArray<nsString, 1> params = {mCurToken};
logWarningErrorToConsole(nsIScriptError::warningFlag,
"couldNotProcessUnknownDirective", params);
@ -838,7 +837,8 @@ nsCSPDirective* nsCSPParser::directiveName() {
// http://www.w3.org/TR/2014/WD-CSP11-20140211/#reflected-xss
// Currently we are not supporting that directive, hence we log a
// warning to the console and ignore the directive including its values.
if (directive == nsIContentSecurityPolicy::REFLECTED_XSS_DIRECTIVE) {
if (CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::REFLECTED_XSS_DIRECTIVE)) {
AutoTArray<nsString, 1> params = {mCurToken};
logWarningErrorToConsole(nsIScriptError::warningFlag,
"notSupportingDirective", params);
@ -849,7 +849,8 @@ nsCSPDirective* nsCSPParser::directiveName() {
// Once all corner cases are resolved we can remove that special
// if-handling here and let the parser just fall through to
// return new nsCSPDirective.
if (directive == nsIContentSecurityPolicy::NAVIGATE_TO_DIRECTIVE &&
if (CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::NAVIGATE_TO_DIRECTIVE) &&
!StaticPrefs::security_csp_enableNavigateTo()) {
AutoTArray<nsString, 1> params = {mCurToken};
logWarningErrorToConsole(nsIScriptError::warningFlag,
@ -859,7 +860,7 @@ nsCSPDirective* nsCSPParser::directiveName() {
// Make sure the directive does not already exist
// (see http://www.w3.org/TR/CSP11/#parsing)
if (mPolicy->hasDirective(directive)) {
if (mPolicy->hasDirective(CSP_StringToCSPDirective(mCurToken))) {
AutoTArray<nsString, 1> params = {mCurToken};
logWarningErrorToConsole(nsIScriptError::warningFlag, "duplicateDirective",
params);
@ -870,9 +871,12 @@ nsCSPDirective* nsCSPParser::directiveName() {
// report-uri, frame-ancestors, and sandbox, see:
// http://www.w3.org/TR/CSP11/#delivery-html-meta-element
if (mDeliveredViaMetaTag &&
((directive == nsIContentSecurityPolicy::REPORT_URI_DIRECTIVE) ||
(directive == nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE) ||
(directive == nsIContentSecurityPolicy::SANDBOX_DIRECTIVE))) {
((CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::REPORT_URI_DIRECTIVE)) ||
(CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE)) ||
(CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::SANDBOX_DIRECTIVE)))) {
// log to the console to indicate that meta CSP is ignoring the directive
AutoTArray<nsString, 1> params = {mCurToken};
logWarningErrorToConsole(nsIScriptError::warningFlag,
@ -881,43 +885,51 @@ nsCSPDirective* nsCSPParser::directiveName() {
}
// special case handling for block-all-mixed-content
if (directive == nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT) {
return new nsBlockAllMixedContentDirective(directive);
if (CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::BLOCK_ALL_MIXED_CONTENT)) {
return new nsBlockAllMixedContentDirective(
CSP_StringToCSPDirective(mCurToken));
}
// special case handling for upgrade-insecure-requests
if (directive == nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE) {
return new nsUpgradeInsecureDirective(directive);
if (CSP_IsDirective(
mCurToken, nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE)) {
return new nsUpgradeInsecureDirective(CSP_StringToCSPDirective(mCurToken));
}
// if we have a child-src, cache it as a fallback for
// * workers (if worker-src is not explicitly specified)
// * frames (if frame-src is not explicitly specified)
if (directive == nsIContentSecurityPolicy::CHILD_SRC_DIRECTIVE) {
mChildSrc = new nsCSPChildSrcDirective(directive);
if (CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::CHILD_SRC_DIRECTIVE)) {
mChildSrc = new nsCSPChildSrcDirective(CSP_StringToCSPDirective(mCurToken));
return mChildSrc;
}
// if we have a frame-src, cache it so we can discard child-src for frames
if (directive == nsIContentSecurityPolicy::FRAME_SRC_DIRECTIVE) {
mFrameSrc = new nsCSPDirective(directive);
if (CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::FRAME_SRC_DIRECTIVE)) {
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 (directive == nsIContentSecurityPolicy::WORKER_SRC_DIRECTIVE) {
mWorkerSrc = new nsCSPDirective(directive);
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 (directive == nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE) {
mScriptSrc = new nsCSPScriptSrcDirective(directive);
if (CSP_IsDirective(mCurToken,
nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE)) {
mScriptSrc =
new nsCSPScriptSrcDirective(CSP_StringToCSPDirective(mCurToken));
return mScriptSrc;
}
return new nsCSPDirective(directive);
return new nsCSPDirective(CSP_StringToCSPDirective(mCurToken));
}
// directive = *WSP [ directive-name [ WSP directive-value ] ]

Просмотреть файл

@ -153,7 +153,8 @@ bool subjectToCSP(nsIURI* aURI, nsContentPolicyType aContentType) {
rv = preloadCsp->ShouldLoad(
contentType, cspEventListener, aContentLocation,
nullptr, // no redirect, aOriginal URL is null.
false, cspNonce, parserCreatedScript, aDecision);
aLoadInfo->GetSendCSPViolationEvents(), cspNonce, parserCreatedScript,
aDecision);
NS_ENSURE_SUCCESS(rv, rv);
// if the preload policy already denied the load, then there
@ -341,9 +342,11 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
bool isPreload = nsContentUtils::IsPreloadType(policyType);
/* On redirect, if the content policy is a preload type, rejecting the
* preload results in the load silently failing, so we pass true to
* the aSendViolationReports parameter. See Bug 1219453.
* preload results in the load silently failing, so we convert preloads to
* the actual type. See Bug 1219453.
*/
policyType =
nsContentUtils::InternalContentPolicyTypeToExternalOrWorker(policyType);
int16_t decision = nsIContentPolicy::ACCEPT;
bool parserCreatedScript = aLoadInfo->GetParserCreatedScript();

Просмотреть файл

@ -255,14 +255,9 @@ void CSP_LogLocalizedStr(const char* aName, const nsTArray<nsString>& aParams,
/* ===== Helpers ============================ */
CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType) {
// We need to know if this is a worker so child-src can handle that case
// correctly.
switch (aType) {
case nsIContentPolicy::TYPE_IMAGE:
case nsIContentPolicy::TYPE_IMAGESET:
case nsIContentPolicy::TYPE_INTERNAL_IMAGE:
case nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD:
case nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON:
return nsIContentSecurityPolicy::IMG_SRC_DIRECTIVE;
// BLock XSLT as script, see bug 910139
@ -280,8 +275,6 @@ CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType) {
return nsIContentSecurityPolicy::SCRIPT_SRC_DIRECTIVE;
case nsIContentPolicy::TYPE_STYLESHEET:
case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET:
case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD:
return nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE;
case nsIContentPolicy::TYPE_FONT:
@ -289,9 +282,6 @@ CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType) {
return nsIContentSecurityPolicy::FONT_SRC_DIRECTIVE;
case nsIContentPolicy::TYPE_MEDIA:
case nsIContentPolicy::TYPE_INTERNAL_AUDIO:
case nsIContentPolicy::TYPE_INTERNAL_VIDEO:
case nsIContentPolicy::TYPE_INTERNAL_TRACK:
return nsIContentSecurityPolicy::MEDIA_SRC_DIRECTIVE;
case nsIContentPolicy::TYPE_WEB_MANIFEST:
@ -303,8 +293,6 @@ CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType) {
return nsIContentSecurityPolicy::WORKER_SRC_DIRECTIVE;
case nsIContentPolicy::TYPE_SUBDOCUMENT:
case nsIContentPolicy::TYPE_INTERNAL_FRAME:
case nsIContentPolicy::TYPE_INTERNAL_IFRAME:
return nsIContentSecurityPolicy::FRAME_SRC_DIRECTIVE;
case nsIContentPolicy::TYPE_WEBSOCKET:
@ -313,14 +301,11 @@ CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType) {
case nsIContentPolicy::TYPE_PING:
case nsIContentPolicy::TYPE_FETCH:
case nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST:
case nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE:
case nsIContentPolicy::TYPE_INTERNAL_FETCH_PRELOAD:
return nsIContentSecurityPolicy::CONNECT_SRC_DIRECTIVE;
case nsIContentPolicy::TYPE_OBJECT:
case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST:
case nsIContentPolicy::TYPE_INTERNAL_EMBED:
case nsIContentPolicy::TYPE_INTERNAL_OBJECT:
return nsIContentSecurityPolicy::OBJECT_SRC_DIRECTIVE;
case nsIContentPolicy::TYPE_DTD:
@ -342,8 +327,7 @@ CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType) {
// Fall through to error for all other directives
// Note that we should never end up here for navigate-to
case nsIContentPolicy::TYPE_INVALID:
case nsIContentPolicy::TYPE_REFRESH:
default:
MOZ_ASSERT(false, "Can not map nsContentPolicyType to CSPDirective");
}
return nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE;
@ -384,6 +368,16 @@ nsCSPHostSrc* CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI) {
bool CSP_IsEmptyDirective(const nsAString& aValue, const nsAString& aDir) {
return (aDir.Length() == 0 && aValue.Length() == 0);
}
bool CSP_IsValidDirective(const nsAString& aDir) {
uint32_t numDirs = (sizeof(CSPStrDirectives) / sizeof(CSPStrDirectives[0]));
for (uint32_t i = 0; i < numDirs; i++) {
if (aDir.LowerCaseEqualsASCII(CSPStrDirectives[i])) {
return true;
}
}
return false;
}
bool CSP_IsDirective(const nsAString& aValue, CSPDirective aDir) {
return aValue.LowerCaseEqualsASCII(CSP_CSPDirectiveToString(aDir));
}
@ -1213,6 +1207,15 @@ void 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<nsString>& outReportURIs) const {
NS_ASSERTION((mDirective == nsIContentSecurityPolicy::REPORT_URI_DIRECTIVE),
"not a report-uri directive");
@ -1262,6 +1265,19 @@ nsCSPChildSrcDirective::nsCSPChildSrcDirective(CSPDirective aDirective)
nsCSPChildSrcDirective::~nsCSPChildSrcDirective() = default;
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) {
return mRestrictFrames;
@ -1279,6 +1295,16 @@ nsCSPScriptSrcDirective::nsCSPScriptSrcDirective(CSPDirective aDirective)
nsCSPScriptSrcDirective::~nsCSPScriptSrcDirective() = default;
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) {
return mRestrictWorkers;
@ -1338,6 +1364,12 @@ nsCSPPolicy::~nsCSPPolicy() {
}
}
bool nsCSPPolicy::permits(CSPDirective aDir, nsIURI* aUri,
bool aSpecific) const {
nsString outp;
return this->permits(aDir, aUri, u""_ns, false, aSpecific, false, outp);
}
bool nsCSPPolicy::permits(CSPDirective aDir, nsIURI* aUri,
const nsAString& aNonce, bool aWasRedirected,
bool aSpecific, bool aParserCreated,
@ -1386,7 +1418,8 @@ bool nsCSPPolicy::permits(CSPDirective aDir, nsIURI* aUri,
return true;
}
bool nsCSPPolicy::allows(CSPDirective aDirective, enum CSPKeyword aKeyword,
bool nsCSPPolicy::allows(nsContentPolicyType aContentType,
enum CSPKeyword aKeyword,
const nsAString& aHashOrNonce,
bool aParserCreated) const {
CSPUTILSLOG(("nsCSPPolicy::allows, aKeyWord: %s, a HashOrNonce: %s",
@ -1397,16 +1430,15 @@ bool nsCSPPolicy::allows(CSPDirective aDirective, enum CSPKeyword aKeyword,
// Try to find a matching directive
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
if (mDirectives[i]->isDefaultDirective()) {
defaultDir = mDirectives[i];
continue;
}
if (mDirectives[i]->equals(aDirective)) {
if (mDirectives[i]->restrictsContentType(aContentType)) {
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:
@ -1433,6 +1465,11 @@ bool nsCSPPolicy::allows(CSPDirective aDirective, enum CSPKeyword aKeyword,
return true;
}
bool nsCSPPolicy::allows(nsContentPolicyType aContentType,
enum CSPKeyword aKeyword) const {
return allows(aContentType, aKeyword, u""_ns, false);
}
void nsCSPPolicy::toString(nsAString& outStr) const {
StringJoinAppend(outStr, u"; "_ns, mDirectives,
[](nsAString& dest, nsCSPDirective* cspDirective) {
@ -1488,22 +1525,21 @@ bool nsCSPPolicy::allowsNavigateTo(nsIURI* aURI, bool aWasRedirected,
* for the ::permits() function family.
*/
void nsCSPPolicy::getDirectiveStringAndReportSampleForContentType(
CSPDirective aDirective, nsAString& outDirective,
nsContentPolicyType aContentType, nsAString& outDirective,
bool* aReportSample) const {
MOZ_ASSERT(aReportSample);
*aReportSample = false;
nsCSPDirective* defaultDir = nullptr;
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
if (mDirectives[i]->isDefaultDirective()) {
defaultDir = mDirectives[i];
continue;
}
if (mDirectives[i]->equals(aDirective)) {
if (mDirectives[i]->restrictsContentType(aContentType)) {
mDirectives[i]->getDirName(outDirective);
*aReportSample = mDirectives[i]->hasReportSampleKeyword();
return;
}
if (mDirectives[i]->isDefaultDirective()) {
defaultDir = mDirectives[i];
}
}
// if we haven't found a matching directive yet,
// the contentType must be restricted by the default directive

Просмотреть файл

@ -104,6 +104,7 @@ inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir) {
return static_cast<CSPDirective>(i);
}
}
NS_ASSERTION(false, "Can not convert unknown Directive to Integer");
return nsIContentSecurityPolicy::NO_DIRECTIVE;
}
@ -197,6 +198,7 @@ class nsCSPHostSrc;
nsCSPHostSrc* CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI);
bool CSP_IsEmptyDirective(const nsAString& aValue, const nsAString& aDir);
bool CSP_IsValidDirective(const nsAString& aDir);
bool CSP_IsDirective(const nsAString& aValue, CSPDirective aDir);
bool CSP_IsKeyword(const nsAString& aValue, enum CSPKeyword aKey);
bool CSP_IsQuotelessKeyword(const nsAString& aKey);
@ -452,6 +454,8 @@ class nsCSPDirective {
mSrcs = aSrcs.Clone();
}
virtual bool restrictsContentType(nsContentPolicyType aContentType) const;
inline bool isDefaultDirective() const {
return mDirective == nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE;
}
@ -488,6 +492,9 @@ class nsCSPChildSrcDirective : public nsCSPDirective {
void setRestrictWorkers() { mRestrictWorkers = true; }
virtual bool restrictsContentType(
nsContentPolicyType aContentType) const override;
virtual bool equals(CSPDirective aDirective) const override;
private:
@ -509,6 +516,9 @@ class nsCSPScriptSrcDirective : public nsCSPDirective {
void setRestrictWorkers() { mRestrictWorkers = true; }
virtual bool restrictsContentType(
nsContentPolicyType aContentType) const override;
virtual bool equals(CSPDirective aDirective) const override;
private:
@ -612,8 +622,10 @@ class nsCSPPolicy {
bool permits(CSPDirective aDirective, nsIURI* aUri, const nsAString& aNonce,
bool aWasRedirected, bool aSpecific, bool aParserCreated,
nsAString& outViolatedDirective) const;
bool allows(CSPDirective aDirective, enum CSPKeyword aKeyword,
bool permits(CSPDirective aDir, nsIURI* aUri, bool aSpecific) const;
bool allows(nsContentPolicyType aContentType, 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;
@ -643,7 +655,7 @@ class nsCSPPolicy {
void getReportURIs(nsTArray<nsString>& outReportURIs) const;
void getDirectiveStringAndReportSampleForContentType(
CSPDirective aDirective, nsAString& outDirective,
nsContentPolicyType aContentType, nsAString& outDirective,
bool* aReportSample) const;
void getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const;

Просмотреть файл

@ -120,7 +120,7 @@ function run_test() {
makeTest(0, { "blocked-uri": "inline" }, false, function(csp) {
let inlineOK = true;
inlineOK = csp.getAllowsInline(
Ci.nsIContentSecurityPolicy.SCRIPT_SRC_DIRECTIVE,
Ci.nsIContentPolicy.TYPE_SCRIPT,
"", // aNonce
false, // aParserCreated
null, // aTriggeringElement
@ -192,7 +192,7 @@ function run_test() {
makeTest(3, { "blocked-uri": "inline" }, true, function(csp) {
let inlineOK = true;
inlineOK = csp.getAllowsInline(
Ci.nsIContentSecurityPolicy.SCRIPT_SRC_DIRECTIVE,
Ci.nsIContentPolicy.TYPE_SCRIPT,
"", // aNonce
false, // aParserCreated
null, // aTriggeringElement

Просмотреть файл

@ -317,11 +317,11 @@ bool nsStyleUtil::CSPAllowsInlineStyle(
}
bool allowInlineStyle = true;
rv = csp->GetAllowsInline(
nsIContentSecurityPolicy::STYLE_SRC_DIRECTIVE, nonce,
false, // aParserCreated only applies to scripts
aElement, nullptr, // nsICSPEventListener
aStyleText, aLineNumber, aColumnNumber, &allowInlineStyle);
rv = csp->GetAllowsInline(nsIContentPolicy::TYPE_STYLESHEET, nonce,
false, // aParserCreated only applies to scripts
aElement, nullptr, // nsICSPEventListener
aStyleText, aLineNumber, aColumnNumber,
&allowInlineStyle);
NS_ENSURE_SUCCESS(rv, false);
return allowInlineStyle;