summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc376
1 files changed, 233 insertions, 143 deletions
diff --git a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
index 9a748e3e923..7ee2f0ba3a7 100644
--- a/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
+++ b/chromium/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -95,13 +95,15 @@ CSPDirectiveList* CSPDirectiveList::Create(
CSPDirectiveList* directives = new CSPDirectiveList(policy, type, source);
directives->Parse(begin, end, should_parse_wasm_eval);
- if (!directives->CheckEval(
- directives->OperativeDirective(directives->script_src_.Get()))) {
+ if (!directives->CheckEval(directives->OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kScriptSrc))) {
String message =
"Refused to evaluate a string as JavaScript because 'unsafe-eval' is "
"not an allowed source of script in the following Content Security "
"Policy directive: \"" +
- directives->OperativeDirective(directives->script_src_.Get())
+ directives
+ ->OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kScriptSrc)
->GetText() +
"\".\n";
directives->SetEvalDisabledErrorMessage(message);
@@ -117,7 +119,7 @@ CSPDirectiveList* CSPDirectiveList::Create(
void CSPDirectiveList::ReportViolation(
const String& directive_text,
- const ContentSecurityPolicy::DirectiveType& effective_type,
+ const ContentSecurityPolicy::DirectiveType effective_type,
const String& console_message,
const KURL& blocked_url,
ResourceRequest::RedirectStatus redirect_status) const {
@@ -135,7 +137,7 @@ void CSPDirectiveList::ReportViolation(
void CSPDirectiveList::ReportViolationWithFrame(
const String& directive_text,
- const ContentSecurityPolicy::DirectiveType& effective_type,
+ const ContentSecurityPolicy::DirectiveType effective_type,
const String& console_message,
const KURL& blocked_url,
LocalFrame* frame) const {
@@ -152,7 +154,7 @@ void CSPDirectiveList::ReportViolationWithFrame(
void CSPDirectiveList::ReportViolationWithLocation(
const String& directive_text,
- const ContentSecurityPolicy::DirectiveType& effective_type,
+ const ContentSecurityPolicy::DirectiveType effective_type,
const String& console_message,
const KURL& blocked_url,
const String& context_url,
@@ -176,7 +178,7 @@ void CSPDirectiveList::ReportViolationWithLocation(
void CSPDirectiveList::ReportEvalViolation(
const String& directive_text,
- const ContentSecurityPolicy::DirectiveType& effective_type,
+ const ContentSecurityPolicy::DirectiveType effective_type,
const String& message,
const KURL& blocked_url,
ScriptState* script_state,
@@ -236,9 +238,9 @@ bool CSPDirectiveList::CheckHash(SourceListDirective* directive,
return !directive || directive->AllowHash(hash_value);
}
-bool CSPDirectiveList::CheckHashedAttributes(
+bool CSPDirectiveList::CheckUnsafeHashesAllowed(
SourceListDirective* directive) const {
- return !directive || directive->AllowHashedAttributes();
+ return !directive || directive->AllowUnsafeHashes();
}
bool CSPDirectiveList::CheckDynamic(SourceListDirective* directive) const {
@@ -375,17 +377,6 @@ bool CSPDirectiveList::CheckMediaType(MediaListDirective* directive,
return directive->Allows(type);
}
-SourceListDirective* CSPDirectiveList::OperativeDirective(
- SourceListDirective* directive) const {
- return directive ? directive : default_src_.Get();
-}
-
-SourceListDirective* CSPDirectiveList::OperativeDirective(
- SourceListDirective* directive,
- SourceListDirective* override) const {
- return directive ? directive : override;
-}
-
bool CSPDirectiveList::CheckEvalAndReportViolation(
SourceListDirective* directive,
const String& console_message,
@@ -515,7 +506,7 @@ bool CSPDirectiveList::CheckInlineAndReportViolation(
bool CSPDirectiveList::CheckSourceAndReportViolation(
SourceListDirective* directive,
const KURL& url,
- const ContentSecurityPolicy::DirectiveType& effective_type,
+ const ContentSecurityPolicy::DirectiveType effective_type,
ResourceRequest::RedirectStatus redirect_status) const {
if (!directive)
return true;
@@ -608,11 +599,12 @@ bool CSPDirectiveList::AllowJavaScriptURLs(
const String& context_url,
const WTF::OrdinalNumber& context_line,
SecurityViolationReportingPolicy reporting_policy) const {
- SourceListDirective* directive = OperativeDirective(script_src_.Get());
+ SourceListDirective* directive =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
return CheckInlineAndReportViolation(
directive,
- "Refused to execute JavaScript URL because it violates the following "
+ "Refused to run the JavaScript URL because it violates the following "
"Content Security Policy directive: ",
element, source, context_url, context_line, true, "sha256-...");
}
@@ -626,10 +618,11 @@ bool CSPDirectiveList::AllowInlineEventHandlers(
const String& context_url,
const WTF::OrdinalNumber& context_line,
SecurityViolationReportingPolicy reporting_policy) const {
- SourceListDirective* directive = OperativeDirective(script_src_.Get());
+ SourceListDirective* directive =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
return CheckInlineAndReportViolation(
- OperativeDirective(script_src_.Get()),
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
"Refused to execute inline event handler because it violates the "
"following Content Security Policy directive: ",
element, source, context_url, context_line, true, "sha256-...");
@@ -645,7 +638,8 @@ bool CSPDirectiveList::AllowInlineScript(
const WTF::OrdinalNumber& context_line,
SecurityViolationReportingPolicy reporting_policy,
const String& content) const {
- SourceListDirective* directive = OperativeDirective(script_src_.Get());
+ SourceListDirective* directive =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
if (IsMatchingNoncePresent(directive, nonce))
return true;
if (element && IsHTMLScriptElement(element) &&
@@ -672,7 +666,8 @@ bool CSPDirectiveList::AllowInlineStyle(
const WTF::OrdinalNumber& context_line,
SecurityViolationReportingPolicy reporting_policy,
const String& content) const {
- SourceListDirective* directive = OperativeDirective(style_src_.Get());
+ SourceListDirective* directive =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kStyleSrc);
if (IsMatchingNoncePresent(directive, nonce))
return true;
if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
@@ -694,13 +689,14 @@ bool CSPDirectiveList::AllowEval(
const String& content) const {
if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
return CheckEvalAndReportViolation(
- OperativeDirective(script_src_.Get()),
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
"Refused to evaluate a string as JavaScript because 'unsafe-eval' is "
"not an allowed source of script in the following Content Security "
"Policy directive: ",
script_state, exception_status, content);
}
- return CheckEval(OperativeDirective(script_src_.Get()));
+ return CheckEval(
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc));
}
bool CSPDirectiveList::AllowWasmEval(
@@ -710,13 +706,14 @@ bool CSPDirectiveList::AllowWasmEval(
const String& content) const {
if (reporting_policy == SecurityViolationReportingPolicy::kReport) {
return CheckWasmEvalAndReportViolation(
- OperativeDirective(script_src_.Get()),
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc),
"Refused to compile or instantiate WebAssembly module because "
"'wasm-eval' is not an allowed source of script in the following "
"Content Security Policy directive: ",
script_state, exception_status, content);
}
- return CheckWasmEval(OperativeDirective(script_src_.Get()));
+ return CheckWasmEval(
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc));
}
bool CSPDirectiveList::AllowPluginType(
@@ -741,7 +738,8 @@ bool CSPDirectiveList::AllowScriptFromSource(
ParserDisposition parser_disposition,
ResourceRequest::RedirectStatus redirect_status,
SecurityViolationReportingPolicy reporting_policy) const {
- SourceListDirective* directive = OperativeDirective(script_src_.Get());
+ SourceListDirective* directive =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc);
if (IsMatchingNoncePresent(directive, nonce))
return true;
if (parser_disposition == kNotParserInserted && AllowDynamic())
@@ -764,11 +762,14 @@ bool CSPDirectiveList::AllowObjectFromSource(
return true;
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- OperativeDirective(object_src_.Get()), url,
- ContentSecurityPolicy::DirectiveType::kObjectSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kObjectSrc),
+ url, ContentSecurityPolicy::DirectiveType::kObjectSrc,
redirect_status)
- : CheckSource(OperativeDirective(object_src_.Get()), url,
- redirect_status);
+ : CheckSource(
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kObjectSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowPrefetchFromSource(
@@ -777,11 +778,14 @@ bool CSPDirectiveList::AllowPrefetchFromSource(
SecurityViolationReportingPolicy reporting_policy) const {
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- OperativeDirective(prefetch_src_.Get()), url,
- ContentSecurityPolicy::DirectiveType::kPrefetchSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kPrefetchSrc),
+ url, ContentSecurityPolicy::DirectiveType::kPrefetchSrc,
redirect_status)
- : CheckSource(OperativeDirective(prefetch_src_.Get()), url,
- redirect_status);
+ : CheckSource(
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kPrefetchSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowFrameFromSource(
@@ -795,8 +799,8 @@ bool CSPDirectiveList::AllowFrameFromSource(
// sources. So, we do this nested set of calls to 'operativeDirective()' to
// grab 'frame-src' if it exists, 'child-src' if it doesn't, and 'defaut-src'
// if neither are available.
- SourceListDirective* which_directive = OperativeDirective(
- frame_src_.Get(), OperativeDirective(child_src_.Get()));
+ SourceListDirective* which_directive =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kFrameSrc);
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
@@ -812,11 +816,13 @@ bool CSPDirectiveList::AllowImageFromSource(
SecurityViolationReportingPolicy reporting_policy) const {
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- OperativeDirective(img_src_.Get()), url,
- ContentSecurityPolicy::DirectiveType::kImgSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kImgSrc),
+ url, ContentSecurityPolicy::DirectiveType::kImgSrc,
redirect_status)
- : CheckSource(OperativeDirective(img_src_.Get()), url,
- redirect_status);
+ : CheckSource(OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kImgSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowStyleFromSource(
@@ -824,15 +830,19 @@ bool CSPDirectiveList::AllowStyleFromSource(
const String& nonce,
ResourceRequest::RedirectStatus redirect_status,
SecurityViolationReportingPolicy reporting_policy) const {
- if (IsMatchingNoncePresent(OperativeDirective(style_src_.Get()), nonce))
+ if (IsMatchingNoncePresent(
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kStyleSrc),
+ nonce))
return true;
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- OperativeDirective(style_src_.Get()), url,
- ContentSecurityPolicy::DirectiveType::kStyleSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kStyleSrc),
+ url, ContentSecurityPolicy::DirectiveType::kStyleSrc,
redirect_status)
- : CheckSource(OperativeDirective(style_src_.Get()), url,
- redirect_status);
+ : CheckSource(OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kStyleSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowFontFromSource(
@@ -841,11 +851,13 @@ bool CSPDirectiveList::AllowFontFromSource(
SecurityViolationReportingPolicy reporting_policy) const {
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- OperativeDirective(font_src_.Get()), url,
- ContentSecurityPolicy::DirectiveType::kFontSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kFontSrc),
+ url, ContentSecurityPolicy::DirectiveType::kFontSrc,
redirect_status)
- : CheckSource(OperativeDirective(font_src_.Get()), url,
- redirect_status);
+ : CheckSource(OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kFontSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowMediaFromSource(
@@ -854,11 +866,13 @@ bool CSPDirectiveList::AllowMediaFromSource(
SecurityViolationReportingPolicy reporting_policy) const {
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- OperativeDirective(media_src_.Get()), url,
- ContentSecurityPolicy::DirectiveType::kMediaSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kMediaSrc),
+ url, ContentSecurityPolicy::DirectiveType::kMediaSrc,
redirect_status)
- : CheckSource(OperativeDirective(media_src_.Get()), url,
- redirect_status);
+ : CheckSource(OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kMediaSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowManifestFromSource(
@@ -867,11 +881,14 @@ bool CSPDirectiveList::AllowManifestFromSource(
SecurityViolationReportingPolicy reporting_policy) const {
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- OperativeDirective(manifest_src_.Get()), url,
- ContentSecurityPolicy::DirectiveType::kManifestSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kManifestSrc),
+ url, ContentSecurityPolicy::DirectiveType::kManifestSrc,
redirect_status)
- : CheckSource(OperativeDirective(manifest_src_.Get()), url,
- redirect_status);
+ : CheckSource(
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kManifestSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowConnectToSource(
@@ -880,11 +897,14 @@ bool CSPDirectiveList::AllowConnectToSource(
SecurityViolationReportingPolicy reporting_policy) const {
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- OperativeDirective(connect_src_.Get()), url,
- ContentSecurityPolicy::DirectiveType::kConnectSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kConnectSrc),
+ url, ContentSecurityPolicy::DirectiveType::kConnectSrc,
redirect_status)
- : CheckSource(OperativeDirective(connect_src_.Get()), url,
- redirect_status);
+ : CheckSource(
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kConnectSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowFormAction(
@@ -893,10 +913,14 @@ bool CSPDirectiveList::AllowFormAction(
SecurityViolationReportingPolicy reporting_policy) const {
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- form_action_.Get(), url,
- ContentSecurityPolicy::DirectiveType::kFormAction,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kFormAction),
+ url, ContentSecurityPolicy::DirectiveType::kFormAction,
redirect_status)
- : CheckSource(form_action_.Get(), url, redirect_status);
+ : CheckSource(
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kFormAction),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowBaseURI(
@@ -906,12 +930,18 @@ bool CSPDirectiveList::AllowBaseURI(
bool result =
reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- base_uri_.Get(), url,
- ContentSecurityPolicy::DirectiveType::kBaseURI, redirect_status)
- : CheckSource(base_uri_.Get(), url, redirect_status);
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kBaseURI),
+ url, ContentSecurityPolicy::DirectiveType::kBaseURI,
+ redirect_status)
+ : CheckSource(OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kBaseURI),
+ url, redirect_status);
if (result &&
- !CheckSource(OperativeDirective(base_uri_.Get()), url, redirect_status)) {
+ !CheckSource(
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kBaseURI),
+ url, redirect_status)) {
UseCounter::Count(policy_->GetDocument(),
WebFeature::kBaseWouldBeBlockedByDefaultSrc);
}
@@ -923,43 +953,19 @@ bool CSPDirectiveList::AllowWorkerFromSource(
const KURL& url,
ResourceRequest::RedirectStatus redirect_status,
SecurityViolationReportingPolicy reporting_policy) const {
- SourceListDirective* worker_src = OperativeDirective(
- worker_src_.Get(), OperativeDirective(script_src_.Get()));
-
if (AllowDynamicWorker())
return true;
- // In CSP2, workers are controlled via 'child-src'. CSP3 moves them to
- // 'script-src'. In order to avoid breaking sites that allowed workers via
- // 'child-src' that would have been blocked via 'script-src', we'll
- // temporarily check whether a worker blocked via 'script-src' would have been
- // allowed under 'child-src'. If the new 'worker-src' directive is present,
- // however, we'll assume that the developer knows what they're asking for, and
- // skip the extra fallback.
- //
- // That is, we'll block 'https://example.com/worker' given the policy
- // "worker-src 'none'", "worker-src 'none'; child-src https://example.com",
- // but we'll allow it given the policy
- // "script-src https://not-example.com; child-src https://example.com"
- // (because 'child-src' allows it) or "child-src https://not-example.com"
- // (because the absent 'script-src' allows it).
- //
- // TODO(mkwst): Remove this once other vendors follow suit.
- // https://crbug.com/662930
- if (!CheckSource(worker_src, url, redirect_status) && !worker_src_ &&
- child_src_ && CheckSource(child_src_, url, redirect_status)) {
- Deprecation::CountDeprecation(
- policy_->GetDocument(),
- WebFeature::kChildSrcAllowedWorkerThatScriptSrcBlocked);
- return true;
- }
-
return reporting_policy == SecurityViolationReportingPolicy::kReport
? CheckSourceAndReportViolation(
- worker_src, url,
- ContentSecurityPolicy::DirectiveType::kWorkerSrc,
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kWorkerSrc),
+ url, ContentSecurityPolicy::DirectiveType::kWorkerSrc,
redirect_status)
- : CheckSource(worker_src, url, redirect_status);
+ : CheckSource(
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kWorkerSrc),
+ url, redirect_status);
}
bool CSPDirectiveList::AllowAncestors(
@@ -967,38 +973,51 @@ bool CSPDirectiveList::AllowAncestors(
const KURL& url,
SecurityViolationReportingPolicy reporting_policy) const {
return reporting_policy == SecurityViolationReportingPolicy::kReport
- ? CheckAncestorsAndReportViolation(frame_ancestors_.Get(), frame,
- url)
- : CheckAncestors(frame_ancestors_.Get(), frame);
+ ? CheckAncestorsAndReportViolation(
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kFrameAncestors),
+ frame, url)
+ : CheckAncestors(
+ OperativeDirective(
+ ContentSecurityPolicy::DirectiveType::kFrameAncestors),
+ frame);
}
-bool CSPDirectiveList::AllowScriptHash(
+bool CSPDirectiveList::AllowHash(
const CSPHashValue& hash_value,
- ContentSecurityPolicy::InlineType type) const {
+ const ContentSecurityPolicy::InlineType type,
+ const ContentSecurityPolicy::DirectiveType directive_type) const {
if (type == ContentSecurityPolicy::InlineType::kAttribute) {
if (!policy_->ExperimentalFeaturesEnabled())
return false;
- if (!CheckHashedAttributes(OperativeDirective(script_src_.Get())))
+ if (!CheckUnsafeHashesAllowed(OperativeDirective(directive_type)))
return false;
}
- return CheckHash(OperativeDirective(script_src_.Get()), hash_value);
+ return CheckHash(OperativeDirective(directive_type), hash_value);
+}
+
+bool CSPDirectiveList::AllowScriptHash(
+ const CSPHashValue& hash_value,
+ ContentSecurityPolicy::InlineType type) const {
+ return AllowHash(hash_value, type,
+ ContentSecurityPolicy::DirectiveType::kScriptSrc);
}
bool CSPDirectiveList::AllowStyleHash(
const CSPHashValue& hash_value,
ContentSecurityPolicy::InlineType type) const {
- if (type != ContentSecurityPolicy::InlineType::kBlock)
- return false;
- return CheckHash(OperativeDirective(style_src_.Get()), hash_value);
+ return AllowHash(hash_value, type,
+ ContentSecurityPolicy::DirectiveType::kStyleSrc);
}
bool CSPDirectiveList::AllowDynamic() const {
- return CheckDynamic(OperativeDirective(script_src_.Get()));
+ return CheckDynamic(
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kScriptSrc));
}
bool CSPDirectiveList::AllowDynamicWorker() const {
- SourceListDirective* worker_src = OperativeDirective(
- worker_src_.Get(), OperativeDirective(script_src_.Get()));
+ SourceListDirective* worker_src =
+ OperativeDirective(ContentSecurityPolicy::DirectiveType::kWorkerSrc);
return CheckDynamic(worker_src);
}
@@ -1407,54 +1426,125 @@ void CSPDirectiveList::AddDirective(const String& name, const String& value) {
}
}
+ContentSecurityPolicy::DirectiveType CSPDirectiveList::FallbackDirective(
+ const ContentSecurityPolicy::DirectiveType current_directive,
+ const ContentSecurityPolicy::DirectiveType original_directive) const {
+ switch (current_directive) {
+ case ContentSecurityPolicy::DirectiveType::kConnectSrc:
+ case ContentSecurityPolicy::DirectiveType::kFontSrc:
+ case ContentSecurityPolicy::DirectiveType::kImgSrc:
+ case ContentSecurityPolicy::DirectiveType::kManifestSrc:
+ case ContentSecurityPolicy::DirectiveType::kMediaSrc:
+ case ContentSecurityPolicy::DirectiveType::kPrefetchSrc:
+ case ContentSecurityPolicy::DirectiveType::kObjectSrc:
+ case ContentSecurityPolicy::DirectiveType::kScriptSrc:
+ case ContentSecurityPolicy::DirectiveType::kStyleSrc:
+ return ContentSecurityPolicy::DirectiveType::kDefaultSrc;
+
+ case ContentSecurityPolicy::DirectiveType::kFrameSrc:
+ case ContentSecurityPolicy::DirectiveType::kWorkerSrc:
+ return ContentSecurityPolicy::DirectiveType::kChildSrc;
+
+ // Because the fallback chain of child-src can be different if we are
+ // checking a worker or a frame request, we need to know the original type
+ // of the request to decide. These are the fallback chains for worker-src
+ // and frame-src specifically.
+
+ // worker-src > child-src > script-src > default-src
+ // frame-src > child-src > default-src
+
+ // Since there are some situations and tests that will operate on the
+ // `child-src` directive directly (like for example the EE subsumption
+ // algorithm), we consider the child-src > default-src fallback path as the
+ // "default" and the worker-src fallback path as an exception.
+ case ContentSecurityPolicy::DirectiveType::kChildSrc:
+ if (original_directive ==
+ ContentSecurityPolicy::DirectiveType::kWorkerSrc)
+ return ContentSecurityPolicy::DirectiveType::kScriptSrc;
+
+ return ContentSecurityPolicy::DirectiveType::kDefaultSrc;
+
+ default:
+ return ContentSecurityPolicy::DirectiveType::kUndefined;
+ }
+}
+
SourceListDirective* CSPDirectiveList::OperativeDirective(
- const ContentSecurityPolicy::DirectiveType& type) const {
+ const ContentSecurityPolicy::DirectiveType type,
+ ContentSecurityPolicy::DirectiveType original_type) const {
+ if (type == ContentSecurityPolicy::DirectiveType::kUndefined) {
+ return nullptr;
+ }
+
+ SourceListDirective* directive;
+ if (original_type == ContentSecurityPolicy::DirectiveType::kUndefined) {
+ original_type = type;
+ }
+
switch (type) {
- // Directives that do not have a default directive.
case ContentSecurityPolicy::DirectiveType::kBaseURI:
- return base_uri_.Get();
+ directive = base_uri_;
+ break;
case ContentSecurityPolicy::DirectiveType::kDefaultSrc:
- return default_src_.Get();
+ directive = default_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kFrameAncestors:
- return frame_ancestors_.Get();
+ directive = frame_ancestors_;
+ break;
case ContentSecurityPolicy::DirectiveType::kFormAction:
- return form_action_.Get();
+ directive = form_action_;
+ break;
case ContentSecurityPolicy::DirectiveType::kNavigateTo:
- return navigate_to_.Get();
- // Directives that have one default directive.
+ directive = navigate_to_;
+ break;
case ContentSecurityPolicy::DirectiveType::kChildSrc:
- return OperativeDirective(child_src_.Get());
+ directive = child_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kConnectSrc:
- return OperativeDirective(connect_src_.Get());
+ directive = connect_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kFontSrc:
- return OperativeDirective(font_src_.Get());
+ directive = font_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kImgSrc:
- return OperativeDirective(img_src_.Get());
+ directive = img_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kManifestSrc:
- return OperativeDirective(manifest_src_.Get());
+ directive = manifest_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kMediaSrc:
- return OperativeDirective(media_src_.Get());
+ directive = media_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kObjectSrc:
- return OperativeDirective(object_src_.Get());
+ directive = object_src_;
+ break;
+ case ContentSecurityPolicy::DirectiveType::kPrefetchSrc:
+ directive = prefetch_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kScriptSrc:
- return OperativeDirective(script_src_.Get());
+ directive = script_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kStyleSrc:
- return OperativeDirective(style_src_.Get());
- // Directives that default to 'child-src' (which defaults to 'default-src')
+ directive = style_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kFrameSrc:
- return OperativeDirective(frame_src_.Get(),
- OperativeDirective(child_src_.Get()));
- // Directives that default to 'script-src' (which defaults to 'default-src')
+ directive = frame_src_;
+ break;
case ContentSecurityPolicy::DirectiveType::kWorkerSrc:
- return OperativeDirective(worker_src_.Get(),
- OperativeDirective(script_src_.Get()));
+ directive = worker_src_;
+ break;
default:
return nullptr;
}
+
+ // if the directive does not exist, rely on the fallback directive
+ return directive ? directive
+ : OperativeDirective(FallbackDirective(type, original_type),
+ original_type);
}
SourceListDirectiveVector CSPDirectiveList::GetSourceVector(
- const ContentSecurityPolicy::DirectiveType& type,
+ const ContentSecurityPolicy::DirectiveType type,
const CSPDirectiveListVector& policies) {
SourceListDirectiveVector source_list_directives;
for (const auto& policy : policies) {
@@ -1472,7 +1562,7 @@ bool CSPDirectiveList::Subsumes(const CSPDirectiveListVector& other) {
// A white-list of directives that we consider for subsumption.
// See more about source lists here:
// https://w3c.github.io/webappsec-csp/#framework-directive-source-list
- ContentSecurityPolicy::DirectiveType directives[] = {
+ static ContentSecurityPolicy::DirectiveType directives[] = {
ContentSecurityPolicy::DirectiveType::kChildSrc,
ContentSecurityPolicy::DirectiveType::kConnectSrc,
ContentSecurityPolicy::DirectiveType::kFontSrc,