| 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 403a7fc926ed0bc2a290ce7c945d471a9339885f..34611c35cf3466b6a3e1401ca7c0c5637baf77bf 100644
|
| --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| @@ -72,6 +72,66 @@
|
| #include <memory>
|
|
|
| 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))
|
| @@ -981,11 +1041,10 @@
|
| m_insecureRequestPolicy |= kUpgradeInsecureRequests;
|
| }
|
|
|
| -static String stripURLForUseInReport(
|
| - ExecutionContext* context,
|
| - const KURL& url,
|
| - RedirectStatus redirectStatus,
|
| - const ContentSecurityPolicy::DirectiveType& effectiveType) {
|
| +static String stripURLForUseInReport(ExecutionContext* context,
|
| + const KURL& url,
|
| + RedirectStatus redirectStatus,
|
| + const String& effectiveDirective) {
|
| if (!url.isValid())
|
| return String();
|
| if (!url.isHierarchical() || url.protocolIs("file"))
|
| @@ -997,8 +1056,10 @@
|
| bool canSafelyExposeURL =
|
| context->getSecurityOrigin()->canRequest(url) ||
|
| (redirectStatus == RedirectStatus::NoRedirect &&
|
| - effectiveType != ContentSecurityPolicy::DirectiveType::FrameSrc &&
|
| - effectiveType != ContentSecurityPolicy::DirectiveType::ObjectSrc);
|
| + !equalIgnoringCase(effectiveDirective,
|
| + ContentSecurityPolicy::FrameSrc) &&
|
| + !equalIgnoringCase(effectiveDirective,
|
| + ContentSecurityPolicy::ObjectSrc));
|
|
|
| if (canSafelyExposeURL) {
|
| // 'KURL::strippedForUseAsReferrer()' dumps 'String()' for non-webby URLs.
|
| @@ -1014,14 +1075,15 @@
|
| SecurityPolicyViolationEventInit& init,
|
| ExecutionContext* context,
|
| const String& directiveText,
|
| - const ContentSecurityPolicy::DirectiveType& effectiveType,
|
| + const String& effectiveDirective,
|
| const KURL& blockedURL,
|
| const String& header,
|
| RedirectStatus redirectStatus,
|
| ContentSecurityPolicyHeaderType headerType,
|
| ContentSecurityPolicy::ViolationType violationType,
|
| int contextLine) {
|
| - if (effectiveType == ContentSecurityPolicy::DirectiveType::FrameAncestors) {
|
| + if (equalIgnoringCase(effectiveDirective,
|
| + ContentSecurityPolicy::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.
|
| @@ -1038,13 +1100,11 @@
|
| break;
|
| case ContentSecurityPolicy::URLViolation:
|
| init.setBlockedURI(stripURLForUseInReport(
|
| - context, blockedURL, redirectStatus, effectiveType));
|
| + context, blockedURL, redirectStatus, effectiveDirective));
|
| break;
|
| }
|
| }
|
|
|
| - String effectiveDirective =
|
| - ContentSecurityPolicy::getDirectiveName(effectiveType);
|
| init.setViolatedDirective(effectiveDirective);
|
| init.setEffectiveDirective(effectiveDirective);
|
| init.setOriginalPolicy(header);
|
| @@ -1069,8 +1129,8 @@
|
| std::unique_ptr<SourceLocation> location = SourceLocation::capture(context);
|
| if (location->lineNumber()) {
|
| KURL source = KURL(ParsedURLString, location->url());
|
| - init.setSourceFile(
|
| - stripURLForUseInReport(context, source, redirectStatus, effectiveType));
|
| + init.setSourceFile(stripURLForUseInReport(context, source, redirectStatus,
|
| + effectiveDirective));
|
| init.setLineNumber(location->lineNumber());
|
| init.setColumnNumber(location->columnNumber());
|
| }
|
| @@ -1078,7 +1138,7 @@
|
|
|
| void ContentSecurityPolicy::reportViolation(
|
| const String& directiveText,
|
| - const DirectiveType& effectiveType,
|
| + const String& effectiveDirective,
|
| const String& consoleMessage,
|
| const KURL& blockedURL,
|
| const Vector<String>& reportEndpoints,
|
| @@ -1095,14 +1155,19 @@
|
| // 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(effectiveType == DirectiveType::ChildSrc ||
|
| - effectiveType == DirectiveType::FrameSrc ||
|
| - effectiveType == DirectiveType::PluginTypes);
|
| + DCHECK(equalIgnoringCase(effectiveDirective,
|
| + ContentSecurityPolicy::ChildSrc) ||
|
| + equalIgnoringCase(effectiveDirective,
|
| + ContentSecurityPolicy::FrameSrc) ||
|
| + equalIgnoringCase(effectiveDirective,
|
| + ContentSecurityPolicy::PluginTypes));
|
| return;
|
| }
|
|
|
| DCHECK((m_executionContext && !contextFrame) ||
|
| - ((effectiveType == DirectiveType::FrameAncestors) && contextFrame));
|
| + (equalIgnoringCase(effectiveDirective,
|
| + ContentSecurityPolicy::FrameAncestors) &&
|
| + contextFrame));
|
|
|
| SecurityPolicyViolationEventInit violationData;
|
|
|
| @@ -1112,8 +1177,9 @@
|
| contextFrame ? contextFrame->document() : m_executionContext;
|
| DCHECK(relevantContext);
|
| gatherSecurityPolicyViolationEventData(
|
| - violationData, relevantContext, directiveText, effectiveType, blockedURL,
|
| - header, redirectStatus, headerType, violationType, contextLine);
|
| + violationData, relevantContext, directiveText, effectiveDirective,
|
| + 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
|
| @@ -1200,8 +1266,8 @@
|
| // document's URL.
|
| DCHECK(!contextFrame || !m_executionContext);
|
| DCHECK(!contextFrame ||
|
| - getDirectiveType(violationData.effectiveDirective()) ==
|
| - DirectiveType::FrameAncestors);
|
| + equalIgnoringCase(violationData.effectiveDirective(),
|
| + FrameAncestors));
|
| KURL url =
|
| contextFrame
|
| ? frame->document()->completeURLWithOverride(
|
| @@ -1303,7 +1369,7 @@
|
| message = optionsMessage;
|
| } else if (equalIgnoringCase(name, policyURI)) {
|
| message = policyURIMessage;
|
| - } else if (getDirectiveType(name) != DirectiveType::Undefined) {
|
| + } else if (isDirectiveName(name)) {
|
| message = "The Content-Security-Policy directive '" + name +
|
| "' is implemented behind a flag which is currently disabled.\n";
|
| level = InfoMessageLevel;
|
| @@ -1490,109 +1556,4 @@
|
| 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
|
|
|