| Index: third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| index 34611c35cf3466b6a3e1401ca7c0c5637baf77bf..403a7fc926ed0bc2a290ce7c945d471a9339885f 100644
|
| --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| @@ -73,66 +73,6 @@
|
|
|
| namespace blink {
|
|
|
| -// CSP Level 1 Directives
|
| -const char ContentSecurityPolicy::ConnectSrc[] = "connect-src";
|
| -const char ContentSecurityPolicy::DefaultSrc[] = "default-src";
|
| -const char ContentSecurityPolicy::FontSrc[] = "font-src";
|
| -const char ContentSecurityPolicy::FrameSrc[] = "frame-src";
|
| -const char ContentSecurityPolicy::ImgSrc[] = "img-src";
|
| -const char ContentSecurityPolicy::MediaSrc[] = "media-src";
|
| -const char ContentSecurityPolicy::ObjectSrc[] = "object-src";
|
| -const char ContentSecurityPolicy::ReportURI[] = "report-uri";
|
| -const char ContentSecurityPolicy::Sandbox[] = "sandbox";
|
| -const char ContentSecurityPolicy::ScriptSrc[] = "script-src";
|
| -const char ContentSecurityPolicy::StyleSrc[] = "style-src";
|
| -
|
| -// CSP Level 2 Directives
|
| -const char ContentSecurityPolicy::BaseURI[] = "base-uri";
|
| -const char ContentSecurityPolicy::ChildSrc[] = "child-src";
|
| -const char ContentSecurityPolicy::FormAction[] = "form-action";
|
| -const char ContentSecurityPolicy::FrameAncestors[] = "frame-ancestors";
|
| -const char ContentSecurityPolicy::PluginTypes[] = "plugin-types";
|
| -
|
| -// CSP Level 3 Directives
|
| -const char ContentSecurityPolicy::ManifestSrc[] = "manifest-src";
|
| -const char ContentSecurityPolicy::WorkerSrc[] = "worker-src";
|
| -
|
| -// Mixed Content Directive
|
| -// https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode
|
| -const char ContentSecurityPolicy::BlockAllMixedContent[] =
|
| - "block-all-mixed-content";
|
| -
|
| -// https://w3c.github.io/webappsec/specs/upgrade/
|
| -const char ContentSecurityPolicy::UpgradeInsecureRequests[] =
|
| - "upgrade-insecure-requests";
|
| -
|
| -// https://mikewest.github.io/cors-rfc1918/#csp
|
| -const char ContentSecurityPolicy::TreatAsPublicAddress[] =
|
| - "treat-as-public-address";
|
| -
|
| -// https://w3c.github.io/webappsec-subresource-integrity/#require-sri-for
|
| -const char ContentSecurityPolicy::RequireSRIFor[] = "require-sri-for";
|
| -
|
| -bool ContentSecurityPolicy::isDirectiveName(const String& name) {
|
| - return (
|
| - equalIgnoringCase(name, ConnectSrc) ||
|
| - equalIgnoringCase(name, DefaultSrc) || equalIgnoringCase(name, FontSrc) ||
|
| - equalIgnoringCase(name, FrameSrc) || equalIgnoringCase(name, ImgSrc) ||
|
| - equalIgnoringCase(name, MediaSrc) || equalIgnoringCase(name, ObjectSrc) ||
|
| - equalIgnoringCase(name, ReportURI) || equalIgnoringCase(name, Sandbox) ||
|
| - equalIgnoringCase(name, ScriptSrc) || equalIgnoringCase(name, StyleSrc) ||
|
| - equalIgnoringCase(name, BaseURI) || equalIgnoringCase(name, ChildSrc) ||
|
| - equalIgnoringCase(name, FormAction) ||
|
| - equalIgnoringCase(name, FrameAncestors) ||
|
| - equalIgnoringCase(name, PluginTypes) ||
|
| - equalIgnoringCase(name, ManifestSrc) ||
|
| - equalIgnoringCase(name, WorkerSrc) ||
|
| - equalIgnoringCase(name, BlockAllMixedContent) ||
|
| - equalIgnoringCase(name, UpgradeInsecureRequests) ||
|
| - equalIgnoringCase(name, TreatAsPublicAddress) ||
|
| - equalIgnoringCase(name, RequireSRIFor));
|
| -}
|
| -
|
| bool ContentSecurityPolicy::isNonceableElement(const Element* element) {
|
| if (!element->fastHasAttribute(HTMLNames::nonceAttr))
|
| return false;
|
| @@ -1041,10 +981,11 @@ void ContentSecurityPolicy::upgradeInsecureRequests() {
|
| m_insecureRequestPolicy |= kUpgradeInsecureRequests;
|
| }
|
|
|
| -static String stripURLForUseInReport(ExecutionContext* context,
|
| - const KURL& url,
|
| - RedirectStatus redirectStatus,
|
| - const String& effectiveDirective) {
|
| +static String stripURLForUseInReport(
|
| + ExecutionContext* context,
|
| + const KURL& url,
|
| + RedirectStatus redirectStatus,
|
| + const ContentSecurityPolicy::DirectiveType& effectiveType) {
|
| if (!url.isValid())
|
| return String();
|
| if (!url.isHierarchical() || url.protocolIs("file"))
|
| @@ -1056,10 +997,8 @@ static String stripURLForUseInReport(ExecutionContext* context,
|
| bool canSafelyExposeURL =
|
| context->getSecurityOrigin()->canRequest(url) ||
|
| (redirectStatus == RedirectStatus::NoRedirect &&
|
| - !equalIgnoringCase(effectiveDirective,
|
| - ContentSecurityPolicy::FrameSrc) &&
|
| - !equalIgnoringCase(effectiveDirective,
|
| - ContentSecurityPolicy::ObjectSrc));
|
| + effectiveType != ContentSecurityPolicy::DirectiveType::FrameSrc &&
|
| + effectiveType != ContentSecurityPolicy::DirectiveType::ObjectSrc);
|
|
|
| if (canSafelyExposeURL) {
|
| // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URLs.
|
| @@ -1075,15 +1014,14 @@ static void gatherSecurityPolicyViolationEventData(
|
| SecurityPolicyViolationEventInit& init,
|
| ExecutionContext* context,
|
| const String& directiveText,
|
| - const String& effectiveDirective,
|
| + const ContentSecurityPolicy::DirectiveType& effectiveType,
|
| const KURL& blockedURL,
|
| const String& header,
|
| RedirectStatus redirectStatus,
|
| ContentSecurityPolicyHeaderType headerType,
|
| ContentSecurityPolicy::ViolationType violationType,
|
| int contextLine) {
|
| - if (equalIgnoringCase(effectiveDirective,
|
| - ContentSecurityPolicy::FrameAncestors)) {
|
| + if (effectiveType == ContentSecurityPolicy::DirectiveType::FrameAncestors) {
|
| // If this load was blocked via 'frame-ancestors', then the URL of
|
| // |document| has not yet been initialized. In this case, we'll set both
|
| // 'documentURI' and 'blockedURI' to the blocked document's URL.
|
| @@ -1100,11 +1038,13 @@ static void gatherSecurityPolicyViolationEventData(
|
| break;
|
| case ContentSecurityPolicy::URLViolation:
|
| init.setBlockedURI(stripURLForUseInReport(
|
| - context, blockedURL, redirectStatus, effectiveDirective));
|
| + context, blockedURL, redirectStatus, effectiveType));
|
| break;
|
| }
|
| }
|
|
|
| + String effectiveDirective =
|
| + ContentSecurityPolicy::getDirectiveName(effectiveType);
|
| init.setViolatedDirective(effectiveDirective);
|
| init.setEffectiveDirective(effectiveDirective);
|
| init.setOriginalPolicy(header);
|
| @@ -1129,8 +1069,8 @@ static void gatherSecurityPolicyViolationEventData(
|
| std::unique_ptr<SourceLocation> location = SourceLocation::capture(context);
|
| if (location->lineNumber()) {
|
| KURL source = KURL(ParsedURLString, location->url());
|
| - init.setSourceFile(stripURLForUseInReport(context, source, redirectStatus,
|
| - effectiveDirective));
|
| + init.setSourceFile(
|
| + stripURLForUseInReport(context, source, redirectStatus, effectiveType));
|
| init.setLineNumber(location->lineNumber());
|
| init.setColumnNumber(location->columnNumber());
|
| }
|
| @@ -1138,7 +1078,7 @@ static void gatherSecurityPolicyViolationEventData(
|
|
|
| void ContentSecurityPolicy::reportViolation(
|
| const String& directiveText,
|
| - const String& effectiveDirective,
|
| + const DirectiveType& effectiveType,
|
| const String& consoleMessage,
|
| const KURL& blockedURL,
|
| const Vector<String>& reportEndpoints,
|
| @@ -1155,19 +1095,14 @@ void ContentSecurityPolicy::reportViolation(
|
| // https://crbug.com/611232 (or move CSP child-src and frame-src checks to the
|
| // browser process - see https://crbug.com/376522).
|
| if (!m_executionContext && !contextFrame) {
|
| - DCHECK(equalIgnoringCase(effectiveDirective,
|
| - ContentSecurityPolicy::ChildSrc) ||
|
| - equalIgnoringCase(effectiveDirective,
|
| - ContentSecurityPolicy::FrameSrc) ||
|
| - equalIgnoringCase(effectiveDirective,
|
| - ContentSecurityPolicy::PluginTypes));
|
| + DCHECK(effectiveType == DirectiveType::ChildSrc ||
|
| + effectiveType == DirectiveType::FrameSrc ||
|
| + effectiveType == DirectiveType::PluginTypes);
|
| return;
|
| }
|
|
|
| DCHECK((m_executionContext && !contextFrame) ||
|
| - (equalIgnoringCase(effectiveDirective,
|
| - ContentSecurityPolicy::FrameAncestors) &&
|
| - contextFrame));
|
| + ((effectiveType == DirectiveType::FrameAncestors) && contextFrame));
|
|
|
| SecurityPolicyViolationEventInit violationData;
|
|
|
| @@ -1177,9 +1112,8 @@ void ContentSecurityPolicy::reportViolation(
|
| contextFrame ? contextFrame->document() : m_executionContext;
|
| DCHECK(relevantContext);
|
| gatherSecurityPolicyViolationEventData(
|
| - violationData, relevantContext, directiveText, effectiveDirective,
|
| - blockedURL, header, redirectStatus, headerType, violationType,
|
| - contextLine);
|
| + violationData, relevantContext, directiveText, effectiveType, blockedURL,
|
| + header, redirectStatus, headerType, violationType, contextLine);
|
|
|
| // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded
|
| // resources should be allowed regardless. We apparently do, however, so
|
| @@ -1266,8 +1200,8 @@ void ContentSecurityPolicy::postViolationReport(
|
| // document's URL.
|
| DCHECK(!contextFrame || !m_executionContext);
|
| DCHECK(!contextFrame ||
|
| - equalIgnoringCase(violationData.effectiveDirective(),
|
| - FrameAncestors));
|
| + getDirectiveType(violationData.effectiveDirective()) ==
|
| + DirectiveType::FrameAncestors);
|
| KURL url =
|
| contextFrame
|
| ? frame->document()->completeURLWithOverride(
|
| @@ -1369,7 +1303,7 @@ void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) {
|
| message = optionsMessage;
|
| } else if (equalIgnoringCase(name, policyURI)) {
|
| message = policyURIMessage;
|
| - } else if (isDirectiveName(name)) {
|
| + } else if (getDirectiveType(name) != DirectiveType::Undefined) {
|
| message = "The Content-Security-Policy directive '" + name +
|
| "' is implemented behind a flag which is currently disabled.\n";
|
| level = InfoMessageLevel;
|
| @@ -1556,4 +1490,109 @@ void ContentSecurityPolicy::didSendViolationReport(const String& report) {
|
| m_violationReportsSent.add(report.impl()->hash());
|
| }
|
|
|
| +const char* ContentSecurityPolicy::getDirectiveName(const DirectiveType& type) {
|
| + switch (type) {
|
| + case DirectiveType::BaseURI:
|
| + return "base-uri";
|
| + case DirectiveType::BlockAllMixedContent:
|
| + return "block-all-mixed-content";
|
| + case DirectiveType::ChildSrc:
|
| + return "child-src";
|
| + case DirectiveType::ConnectSrc:
|
| + return "connect-src";
|
| + case DirectiveType::DefaultSrc:
|
| + return "default-src";
|
| + case DirectiveType::FrameAncestors:
|
| + return "frame-ancestors";
|
| + case DirectiveType::FrameSrc:
|
| + return "frame-src";
|
| + case DirectiveType::FontSrc:
|
| + return "font-src";
|
| + case DirectiveType::FormAction:
|
| + return "form-action";
|
| + case DirectiveType::ImgSrc:
|
| + return "img-src";
|
| + case DirectiveType::ManifestSrc:
|
| + return "manifest-src";
|
| + case DirectiveType::MediaSrc:
|
| + return "media-src";
|
| + case DirectiveType::ObjectSrc:
|
| + return "object-src";
|
| + case DirectiveType::PluginTypes:
|
| + return "plugin-types";
|
| + case DirectiveType::ReportURI:
|
| + return "report-uri";
|
| + case DirectiveType::RequireSRIFor:
|
| + return "require-sri-for";
|
| + case DirectiveType::Sandbox:
|
| + return "sandbox";
|
| + case DirectiveType::ScriptSrc:
|
| + return "script-src";
|
| + case DirectiveType::StyleSrc:
|
| + return "style-src";
|
| + case DirectiveType::TreatAsPublicAddress:
|
| + return "treat-as-public-address";
|
| + case DirectiveType::UpgradeInsecureRequests:
|
| + return "upgrade-insecure-requests";
|
| + case DirectiveType::WorkerSrc:
|
| + return "worker-src";
|
| + case DirectiveType::Undefined:
|
| + NOTREACHED();
|
| + return "";
|
| + }
|
| +
|
| + NOTREACHED();
|
| + return "";
|
| +}
|
| +
|
| +ContentSecurityPolicy::DirectiveType ContentSecurityPolicy::getDirectiveType(
|
| + const String& name) {
|
| + if (name == "base-uri")
|
| + return DirectiveType::BaseURI;
|
| + if (name == "block-all-mixed-content")
|
| + return DirectiveType::BlockAllMixedContent;
|
| + if (name == "child-src")
|
| + return DirectiveType::ChildSrc;
|
| + if (name == "connect-src")
|
| + return DirectiveType::ConnectSrc;
|
| + if (name == "default-src")
|
| + return DirectiveType::DefaultSrc;
|
| + if (name == "frame-ancestors")
|
| + return DirectiveType::FrameAncestors;
|
| + if (name == "frame-src")
|
| + return DirectiveType::FrameSrc;
|
| + if (name == "font-src")
|
| + return DirectiveType::FontSrc;
|
| + if (name == "form-action")
|
| + return DirectiveType::FormAction;
|
| + if (name == "img-src")
|
| + return DirectiveType::ImgSrc;
|
| + if (name == "manifest-src")
|
| + return DirectiveType::ManifestSrc;
|
| + if (name == "media-src")
|
| + return DirectiveType::MediaSrc;
|
| + if (name == "object-src")
|
| + return DirectiveType::ObjectSrc;
|
| + if (name == "plugin-types")
|
| + return DirectiveType::PluginTypes;
|
| + if (name == "report-uri")
|
| + return DirectiveType::ReportURI;
|
| + if (name == "require-sri-for")
|
| + return DirectiveType::RequireSRIFor;
|
| + if (name == "sandbox")
|
| + return DirectiveType::Sandbox;
|
| + if (name == "script-src")
|
| + return DirectiveType::ScriptSrc;
|
| + if (name == "style-src")
|
| + return DirectiveType::StyleSrc;
|
| + if (name == "treat-as-public-address")
|
| + return DirectiveType::TreatAsPublicAddress;
|
| + if (name == "upgrade-insecure-requests")
|
| + return DirectiveType::UpgradeInsecureRequests;
|
| + if (name == "worker-src")
|
| + return DirectiveType::WorkerSrc;
|
| +
|
| + return DirectiveType::Undefined;
|
| +}
|
| +
|
| } // namespace blink
|
|
|