| Index: Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| diff --git a/Source/core/frame/csp/ContentSecurityPolicy.cpp b/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| index 80af84f042786d4b885d3329b8afde7e1ac9fc02..3a17d992d178f27499432c74fded97f6e7afdeac 100644
|
| --- a/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| +++ b/Source/core/frame/csp/ContentSecurityPolicy.cpp
|
| @@ -338,11 +338,11 @@ bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u
|
| return true;
|
| }
|
|
|
| -template<bool (CSPDirectiveList::*allowed)(LocalFrame*, ContentSecurityPolicy::ReportingStatus) const>
|
| -bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus)
|
| +template<bool (CSPDirectiveList::*allowed)(LocalFrame*, const KURL&, ContentSecurityPolicy::ReportingStatus) const>
|
| +bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame* frame, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
|
| {
|
| for (size_t i = 0; i < policies.size(); ++i) {
|
| - if (!(policies[i].get()->*allowed)(frame, reportingStatus))
|
| + if (!(policies[i].get()->*allowed)(frame, url, reportingStatus))
|
| return false;
|
| }
|
| return true;
|
| @@ -509,9 +509,9 @@ bool ContentSecurityPolicy::allowBaseURI(const KURL& url, ContentSecurityPolicy:
|
| return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
|
| }
|
|
|
| -bool ContentSecurityPolicy::allowAncestors(LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| +bool ContentSecurityPolicy::allowAncestors(LocalFrame* frame, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| {
|
| - return isAllowedByAllWithFrame<&CSPDirectiveList::allowAncestors>(m_policies, frame, reportingStatus);
|
| + return isAllowedByAllWithFrame<&CSPDirectiveList::allowAncestors>(m_policies, frame, url, reportingStatus);
|
| }
|
|
|
| bool ContentSecurityPolicy::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
|
| @@ -603,9 +603,17 @@ static String stripURLForUseInReport(Document* document, const KURL& url)
|
|
|
| static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventInit& init, Document* document, const String& directiveText, const String& effectiveDirective, const KURL& blockedURL, const String& header)
|
| {
|
| - init.documentURI = document->url().string();
|
| + 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.
|
| + init.documentURI = blockedURL.string();
|
| + init.blockedURI = blockedURL.string();
|
| + } else {
|
| + init.documentURI = document->url().string();
|
| + init.blockedURI = stripURLForUseInReport(document, blockedURL);
|
| + }
|
| init.referrer = document->referrer();
|
| - init.blockedURI = stripURLForUseInReport(document, blockedURL);
|
| init.violatedDirective = directiveText;
|
| init.effectiveDirective = effectiveDirective;
|
| init.originalPolicy = header;
|
| @@ -631,14 +639,12 @@ static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventI
|
| }
|
| }
|
|
|
| -void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const String& header)
|
| +void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<String>& reportEndpoints, const String& header, LocalFrame* contextFrame)
|
| {
|
| - // FIXME: Support sending 'frame-ancestor' reports (which occur before we're bound to an execution context)
|
| - if (!m_executionContext)
|
| - return;
|
| + ASSERT((m_executionContext && !contextFrame) || (equalIgnoringCase(effectiveDirective, ContentSecurityPolicy::FrameAncestors) && contextFrame));
|
|
|
| // FIXME: Support sending reports from worker.
|
| - Document* document = this->document();
|
| + Document* document = contextFrame ? contextFrame->document() : this->document();
|
| if (!document)
|
| return;
|
|
|
| @@ -689,8 +695,15 @@ void ContentSecurityPolicy::reportViolation(const String& directiveText, const S
|
|
|
| RefPtr<FormData> report = FormData::create(stringifiedReport.utf8());
|
|
|
| - for (size_t i = 0; i < reportEndpoints.size(); ++i)
|
| + for (size_t i = 0; i < reportEndpoints.size(); ++i) {
|
| + // 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));
|
| + KURL endpoint = contextFrame ? frame->document()->completeURLWithOverride(reportEndpoints[i], blockedURL) : completeURL(reportEndpoints[i]);
|
| PingLoader::sendViolationReport(frame, completeURL(reportEndpoints[i]), report, PingLoader::ContentSecurityPolicyViolationReport);
|
| + }
|
|
|
| didSendViolationReport(stringifiedReport);
|
| }
|
| @@ -807,9 +820,11 @@ void ContentSecurityPolicy::logToConsole(const String& message, MessageLevel lev
|
| logToConsole(ConsoleMessage::create(SecurityMessageSource, level, message));
|
| }
|
|
|
| -void ContentSecurityPolicy::logToConsole(PassRefPtrWillBeRawPtr<ConsoleMessage> consoleMessage)
|
| +void ContentSecurityPolicy::logToConsole(PassRefPtrWillBeRawPtr<ConsoleMessage> consoleMessage, LocalFrame* frame)
|
| {
|
| - if (m_executionContext)
|
| + if (frame)
|
| + frame->document()->addConsoleMessage(consoleMessage);
|
| + else if (m_executionContext)
|
| m_executionContext->addConsoleMessage(consoleMessage);
|
| else
|
| m_consoleMessages.append(consoleMessage);
|
|
|