Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp

Issue 2020223002: Refactor nonce support. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@inline
Patch Set: Rebase. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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)

Powered by Google App Engine
This is Rietveld 408576698