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

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

Issue 2500383002: CSP: Fire 'securitypolicyviolation' events in Workers. (Closed)
Patch Set: Feedback. Created 4 years, 1 month 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
« no previous file with comments | « third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 b12b47f5c52ab889159ba2a33ddd2556c8935d08..4216d8cb9a891b8c0ef88f2693a2f05b0fd380c7 100644
--- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -48,6 +48,7 @@
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/loader/PingLoader.h"
+#include "core/workers/WorkerGlobalScope.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/json/JSONValues.h"
#include "platform/network/ContentSecurityPolicyParsers.h"
@@ -1040,7 +1041,7 @@ void ContentSecurityPolicy::upgradeInsecureRequests() {
m_insecureRequestPolicy |= kUpgradeInsecureRequests;
}
-static String stripURLForUseInReport(Document* document,
+static String stripURLForUseInReport(ExecutionContext* context,
const KURL& url,
RedirectStatus redirectStatus,
const String& effectiveDirective) {
@@ -1053,7 +1054,7 @@ static String stripURLForUseInReport(Document* document,
// (and, by extension, in plugin documents), strip cross-origin 'frame-src'
// and 'object-src' violations down to an origin. https://crbug.com/633306
bool canSafelyExposeURL =
- document->getSecurityOrigin()->canRequest(url) ||
+ context->getSecurityOrigin()->canRequest(url) ||
(redirectStatus == RedirectStatus::NoRedirect &&
!equalIgnoringCase(effectiveDirective,
ContentSecurityPolicy::FrameSrc) &&
@@ -1072,7 +1073,7 @@ static String stripURLForUseInReport(Document* document,
static void gatherSecurityPolicyViolationEventData(
SecurityPolicyViolationEventInit& init,
- Document* document,
+ ExecutionContext* context,
const String& directiveText,
const String& effectiveDirective,
const KURL& blockedURL,
@@ -1089,7 +1090,7 @@ static void gatherSecurityPolicyViolationEventData(
init.setDocumentURI(blockedURL.getString());
init.setBlockedURI(blockedURL.getString());
} else {
- init.setDocumentURI(document->url().getString());
+ init.setDocumentURI(context->url().getString());
switch (violationType) {
case ContentSecurityPolicy::InlineViolation:
init.setBlockedURI("inline");
@@ -1099,11 +1100,11 @@ static void gatherSecurityPolicyViolationEventData(
break;
case ContentSecurityPolicy::URLViolation:
init.setBlockedURI(stripURLForUseInReport(
- document, blockedURL, redirectStatus, effectiveDirective));
+ context, blockedURL, redirectStatus, effectiveDirective));
break;
}
}
- init.setReferrer(document->referrer());
+
init.setViolatedDirective(effectiveDirective);
init.setEffectiveDirective(effectiveDirective);
init.setOriginalPolicy(header);
@@ -1115,13 +1116,20 @@ static void gatherSecurityPolicyViolationEventData(
init.setColumnNumber(0);
init.setStatusCode(0);
- if (!SecurityOrigin::isSecure(document->url()) && document->loader())
- init.setStatusCode(document->loader()->response().httpStatusCode());
+ // TODO(mkwst): We only have referrer and status code information for
+ // Documents. It would be nice to get them for Workers as well.
+ if (context->isDocument()) {
+ Document* document = toDocument(context);
+ DCHECK(document);
+ init.setReferrer(document->referrer());
+ if (!SecurityOrigin::isSecure(context->url()) && document->loader())
+ init.setStatusCode(document->loader()->response().httpStatusCode());
+ }
- std::unique_ptr<SourceLocation> location = SourceLocation::capture(document);
+ std::unique_ptr<SourceLocation> location = SourceLocation::capture(context);
if (location->lineNumber()) {
KURL source = KURL(ParsedURLString, location->url());
- init.setSourceFile(stripURLForUseInReport(document, source, redirectStatus,
+ init.setSourceFile(stripURLForUseInReport(context, source, redirectStatus,
effectiveDirective));
init.setLineNumber(location->lineNumber());
init.setColumnNumber(location->columnNumber());
@@ -1156,21 +1164,22 @@ void ContentSecurityPolicy::reportViolation(
return;
}
- ASSERT((m_executionContext && !contextFrame) ||
+ DCHECK((m_executionContext && !contextFrame) ||
(equalIgnoringCase(effectiveDirective,
ContentSecurityPolicy::FrameAncestors) &&
contextFrame));
- // FIXME: Support sending reports from worker.
- Document* document =
- contextFrame ? contextFrame->document() : this->document();
- if (!document)
- return;
-
SecurityPolicyViolationEventInit violationData;
+
+ // If we're processing 'frame-ancestors', use |contextFrame|'s execution
+ // context to gather data. Otherwise, use the policy's execution context.
+ ExecutionContext* relevantContext =
+ contextFrame ? contextFrame->document() : m_executionContext;
+ DCHECK(relevantContext);
gatherSecurityPolicyViolationEventData(
- violationData, document, directiveText, effectiveDirective, 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
@@ -1178,7 +1187,31 @@ void ContentSecurityPolicy::reportViolation(
// https://crbug.com/524356 for detail.
if (!violationData.sourceFile().isEmpty() &&
SchemeRegistry::schemeShouldBypassContentSecurityPolicy(
- KURL(ParsedURLString, violationData.sourceFile()).protocol()))
+ KURL(ParsedURLString, violationData.sourceFile()).protocol())) {
+ return;
+ }
+
+ postViolationReport(violationData, contextFrame, reportEndpoints);
+
+ // Fire a violation event if we're working within an execution context (e.g.
+ // we're not processing 'frame-ancestors').
+ if (m_executionContext) {
+ m_executionContext->postTask(
+ BLINK_FROM_HERE,
+ createSameThreadTask(&ContentSecurityPolicy::dispatchViolationEvents,
+ wrapPersistent(this), violationData,
+ wrapPersistent(element)));
+ }
+}
+
+void ContentSecurityPolicy::postViolationReport(
+ const SecurityPolicyViolationEventInit& violationData,
+ LocalFrame* contextFrame,
+ const Vector<String>& reportEndpoints) {
+ // TODO(mkwst): Support POSTing violation reports from a Worker.
+ Document* document =
+ contextFrame ? contextFrame->document() : this->document();
+ if (!document)
return;
// We need to be careful here when deciding what information to send to the
@@ -1233,41 +1266,42 @@ void ContentSecurityPolicy::reportViolation(
// document's URL.
DCHECK(!contextFrame || !m_executionContext);
DCHECK(!contextFrame ||
- equalIgnoringCase(effectiveDirective, FrameAncestors));
+ equalIgnoringCase(violationData.effectiveDirective(),
+ FrameAncestors));
KURL url =
contextFrame
- ? frame->document()->completeURLWithOverride(endpoint, blockedURL)
+ ? frame->document()->completeURLWithOverride(
+ endpoint, KURL(ParsedURLString, violationData.blockedURI()))
: completeURL(endpoint);
PingLoader::sendViolationReport(
frame, url, report, PingLoader::ContentSecurityPolicyViolationReport);
}
}
-
- document->postTask(
- BLINK_FROM_HERE,
- createSameThreadTask(&ContentSecurityPolicy::dispatchViolationEvents,
- wrapPersistent(this), violationData,
- wrapPersistent(element), wrapPersistent(document)));
}
void ContentSecurityPolicy::dispatchViolationEvents(
const SecurityPolicyViolationEventInit& violationData,
- Element* element,
- Document* document) {
- // If the document is detached or closed (thus clearing its event queue)
+ Element* element) {
+ // If the context is detached or closed (thus clearing its event queue)
// between the violation occuring and this event dispatch, exit early.
- if (!document->domWindow() || !document->domWindow()->getEventQueue())
+ EventQueue* queue = m_executionContext->getEventQueue();
+ if (!queue)
return;
SecurityPolicyViolationEvent* event = SecurityPolicyViolationEvent::create(
EventTypeNames::securitypolicyviolation, violationData);
DCHECK(event->bubbles());
- if (element && element->isConnected() && element->document() == document) {
- event->setTarget(element);
- document->domWindow()->getEventQueue()->enqueueEvent(event);
- } else {
- document->domWindow()->enqueueDocumentEvent(event);
+
+ if (m_executionContext->isDocument()) {
+ Document* document = toDocument(m_executionContext);
+ if (element && element->isConnected() && element->document() == document)
+ event->setTarget(element);
+ else
+ event->setTarget(document);
+ } else if (m_executionContext->isWorkerGlobalScope()) {
+ event->setTarget(toWorkerGlobalScope(m_executionContext));
}
+ queue->enqueueEvent(event);
}
void ContentSecurityPolicy::reportMixedContent(const KURL& mixedURL,
« no previous file with comments | « third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698