| 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 7cdbb53cb8b237c09276f2d5dc9c28cf1efbbf3d..3f378187b81d6e7ce58f91da81c9143e6dc3ba2b 100644
|
| --- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| @@ -382,36 +382,15 @@ bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const Str
|
| return isAllowed;
|
| }
|
|
|
| -template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus, const String& content) const>
|
| -bool isAllowedByAllWithContextAndContent(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus, const String& content)
|
| +template <bool (CSPDirectiveList::*allowed)(const String&, const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus, const String& content) const>
|
| +bool isAllowedByAllWithContextAndContent(const CSPDirectiveListVector& policies, const String& contextURL, const String& nonce, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus, const String& content)
|
| {
|
| bool isAllowed = true;
|
| for (const auto& policy : policies)
|
| - isAllowed &= (policy.get()->*allowed)(contextURL, contextLine, reportingStatus, content);
|
| + isAllowed &= (policy.get()->*allowed)(contextURL, nonce, contextLine, reportingStatus, content);
|
| return isAllowed;
|
| }
|
|
|
| -template<CSPDirectiveList::NoncePolicyDisposition (CSPDirectiveList::*allowed)(const String&) const>
|
| -bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce)
|
| -{
|
| - bool isExplicitlyAllowed = false;
|
| - for (const auto& policy : policies) {
|
| - // TODO(mkwst): We skip report-only policies here, because the result is used more or
|
| - // less as a bypass in ScriptLoader. If we return true, we don't apply policy, but
|
| - // we only return true if all policies match. This is a temporary workaround; a
|
| - // better fix would be to delay the nonce processing until such time as the whitelist
|
| - // processing fails. https://crbug.com/611652
|
| - if (policy.get()->headerType() == ContentSecurityPolicyHeaderTypeEnforce) {
|
| - CSPDirectiveList::NoncePolicyDisposition policyDisposition = (policy.get()->*allowed)(nonce);
|
| - if (policyDisposition == CSPDirectiveList::NoncePolicyDisposition::Denied)
|
| - return false;
|
| - if (policyDisposition == CSPDirectiveList::NoncePolicyDisposition::Allowed)
|
| - isExplicitlyAllowed = true;
|
| - }
|
| - }
|
| - return isExplicitlyAllowed;
|
| -}
|
| -
|
| template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&, ContentSecurityPolicy::InlineType) const>
|
| bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHashValue& hashValue, ContentSecurityPolicy::InlineType type)
|
| {
|
| @@ -433,6 +412,18 @@ bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u
|
| return isAllowed;
|
| }
|
|
|
| +template <bool (CSPDirectiveList::*allowFromURLWithNonce)(const KURL&, const String& nonce, RedirectStatus, ContentSecurityPolicy::ReportingStatus) const>
|
| +bool isAllowedByAllWithURLWithNonce(const CSPDirectiveListVector& policies, const KURL& url, const String& nonce, RedirectStatus redirectStatus, ContentSecurityPolicy::ReportingStatus reportingStatus)
|
| +{
|
| + if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
|
| + return true;
|
| +
|
| + bool isAllowed = true;
|
| + for (const auto& policy : policies)
|
| + isAllowed &= (policy.get()->*allowFromURLWithNonce)(url, nonce, redirectStatus, reportingStatus);
|
| + return isAllowed;
|
| +}
|
| +
|
| template<bool (CSPDirectiveList::*allowed)(LocalFrame*, const KURL&, ContentSecurityPolicy::ReportingStatus) const>
|
| bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame* frame, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
|
| {
|
| @@ -490,16 +481,16 @@ bool ContentSecurityPolicy::allowInlineEventHandler(const String& source, const
|
| return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
|
| }
|
|
|
| -bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& scriptContent, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| +bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const String& nonce, const WTF::OrdinalNumber& contextLine, const String& scriptContent, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| {
|
| - return isAllowedByAllWithContextAndContent<&CSPDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus, scriptContent);
|
| + return isAllowedByAllWithContextAndContent<&CSPDirectiveList::allowInlineScript>(m_policies, contextURL, nonce, contextLine, reportingStatus, scriptContent);
|
| }
|
|
|
| -bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& styleContent, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| +bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const String& nonce, const WTF::OrdinalNumber& contextLine, const String& styleContent, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| {
|
| if (m_overrideInlineStyleAllowed)
|
| return true;
|
| - return isAllowedByAllWithContextAndContent<&CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus, styleContent);
|
| + return isAllowedByAllWithContextAndContent<&CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, nonce, contextLine, reportingStatus, styleContent);
|
| }
|
|
|
| bool ContentSecurityPolicy::allowEval(ScriptState* scriptState, ContentSecurityPolicy::ReportingStatus reportingStatus, ContentSecurityPolicy::ExceptionStatus exceptionStatus) const
|
| @@ -554,19 +545,9 @@ bool ContentSecurityPolicy::allowPluginTypeForDocument(const Document& document,
|
| return true;
|
| }
|
|
|
| -bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url, RedirectStatus redirectStatus, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| +bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url, const String& nonce, RedirectStatus redirectStatus, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| {
|
| - return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, redirectStatus, reportingStatus);
|
| -}
|
| -
|
| -bool ContentSecurityPolicy::allowScriptWithNonce(const String& nonce) const
|
| -{
|
| - return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_policies, nonce);
|
| -}
|
| -
|
| -bool ContentSecurityPolicy::allowStyleWithNonce(const String& nonce) const
|
| -{
|
| - return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policies, nonce);
|
| + return isAllowedByAllWithURLWithNonce<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, nonce, redirectStatus, reportingStatus);
|
| }
|
|
|
| bool ContentSecurityPolicy::allowScriptWithHash(const String& source, InlineType type) const
|
| @@ -579,7 +560,7 @@ bool ContentSecurityPolicy::allowStyleWithHash(const String& source, InlineType
|
| return checkDigest<&CSPDirectiveList::allowStyleHash>(source, type, m_styleHashAlgorithmsUsed, m_policies);
|
| }
|
|
|
| -bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context, const KURL& url, RedirectStatus redirectStatus, ReportingStatus reportingStatus) const
|
| +bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context, const KURL& url, const String& nonce, RedirectStatus redirectStatus, ReportingStatus reportingStatus) const
|
| {
|
| switch (context) {
|
| case WebURLRequest::RequestContextAudio:
|
| @@ -608,7 +589,7 @@ bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context,
|
| case WebURLRequest::RequestContextImport:
|
| case WebURLRequest::RequestContextScript:
|
| case WebURLRequest::RequestContextXSLT:
|
| - return allowScriptFromSource(url, redirectStatus, reportingStatus);
|
| + return allowScriptFromSource(url, nonce, redirectStatus, reportingStatus);
|
| case WebURLRequest::RequestContextManifest:
|
| return allowManifestFromSource(url, redirectStatus, reportingStatus);
|
| case WebURLRequest::RequestContextServiceWorker:
|
| @@ -616,7 +597,7 @@ bool ContentSecurityPolicy::allowRequest(WebURLRequest::RequestContext context,
|
| case WebURLRequest::RequestContextWorker:
|
| return allowWorkerContextFromSource(url, redirectStatus, reportingStatus);
|
| case WebURLRequest::RequestContextStyle:
|
| - return allowStyleFromSource(url, redirectStatus, reportingStatus);
|
| + return allowStyleFromSource(url, nonce, redirectStatus, reportingStatus);
|
| case WebURLRequest::RequestContextCSPReport:
|
| case WebURLRequest::RequestContextDownload:
|
| case WebURLRequest::RequestContextHyperlink:
|
| @@ -660,11 +641,11 @@ bool ContentSecurityPolicy::allowImageFromSource(const KURL& url, RedirectStatus
|
| return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(m_policies, url, redirectStatus, reportingStatus);
|
| }
|
|
|
| -bool ContentSecurityPolicy::allowStyleFromSource(const KURL& url, RedirectStatus redirectStatus, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| +bool ContentSecurityPolicy::allowStyleFromSource(const KURL& url, const String& nonce, RedirectStatus redirectStatus, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| {
|
| if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol(), SchemeRegistry::PolicyAreaStyle))
|
| return true;
|
| - return isAllowedByAllWithURL<&CSPDirectiveList::allowStyleFromSource>(m_policies, url, redirectStatus, reportingStatus);
|
| + return isAllowedByAllWithURLWithNonce<&CSPDirectiveList::allowStyleFromSource>(m_policies, url, nonce, redirectStatus, reportingStatus);
|
| }
|
|
|
| bool ContentSecurityPolicy::allowFontFromSource(const KURL& url, RedirectStatus redirectStatus, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| @@ -697,7 +678,7 @@ bool ContentSecurityPolicy::allowWorkerContextFromSource(const KURL& url, Redire
|
| // CSP 1.1 moves workers from 'script-src' to the new 'child-src'. Measure the impact of this backwards-incompatible change.
|
| if (Document* document = this->document()) {
|
| UseCounter::count(*document, UseCounter::WorkerSubjectToCSP);
|
| - if (isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, redirectStatus, SuppressReport) && !isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, redirectStatus, SuppressReport))
|
| + if (isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, redirectStatus, SuppressReport) && !isAllowedByAllWithURLWithNonce<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, AtomicString(), redirectStatus, SuppressReport))
|
| UseCounter::count(*document, UseCounter::WorkerAllowedByChildBlockedByScript);
|
| }
|
|
|
| @@ -859,18 +840,9 @@ void ContentSecurityPolicy::reportViolation(const String& directiveText, const S
|
| if (!document)
|
| return;
|
|
|
| - LocalFrame* frame = document->frame();
|
| - if (!frame)
|
| - return;
|
| -
|
| SecurityPolicyViolationEventInit violationData;
|
| gatherSecurityPolicyViolationEventData(violationData, document, directiveText, effectiveDirective, blockedURL, header, redirectStatus, violationType, contextLine);
|
|
|
| - frame->localDOMWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::create(EventTypeNames::securitypolicyviolation, violationData));
|
| -
|
| - if (reportEndpoints.isEmpty())
|
| - return;
|
| -
|
| // TODO(mkwst): Obviously, we shouldn't hit this check, as extension-loaded
|
| // resources should be allowed regardless. We apparently do, however, so
|
| // we should at least stop spamming reporting endpoints. See
|
| @@ -909,20 +881,24 @@ void ContentSecurityPolicy::reportViolation(const String& directiveText, const S
|
|
|
| if (!shouldSendViolationReport(stringifiedReport))
|
| return;
|
| + didSendViolationReport(stringifiedReport);
|
|
|
| RefPtr<EncodedFormData> report = EncodedFormData::create(stringifiedReport.utf8());
|
|
|
| + LocalFrame* frame = document->frame();
|
| + if (!frame)
|
| + return;
|
| + frame->localDOMWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::create(EventTypeNames::securitypolicyviolation, violationData));
|
| +
|
| for (const String& endpoint : reportEndpoints) {
|
| // If we have a context frame we're dealing with 'frame-ancestors' and we don't have our
|
| // own execution context. Use the frame's document to complete the endpoint URL, overriding
|
| // its URL with the blocked document's URL.
|
| - ASSERT(!contextFrame || !m_executionContext);
|
| - ASSERT(!contextFrame || equalIgnoringCase(effectiveDirective, FrameAncestors));
|
| + DCHECK(!contextFrame || !m_executionContext);
|
| + DCHECK(!contextFrame || equalIgnoringCase(effectiveDirective, FrameAncestors));
|
| KURL url = contextFrame ? frame->document()->completeURLWithOverride(endpoint, blockedURL) : completeURL(endpoint);
|
| PingLoader::sendViolationReport(frame, url, report, PingLoader::ContentSecurityPolicyViolationReport);
|
| }
|
| -
|
| - didSendViolationReport(stringifiedReport);
|
| }
|
|
|
| void ContentSecurityPolicy::reportMixedContent(const KURL& mixedURL, RedirectStatus redirectStatus)
|
|
|