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

Unified Diff: content/browser/frame_host/navigation_request.cc

Issue 2909513002: Move PlzNavigate frame-src CSP check to NavigationRequest (Closed)
Patch Set: comment tweaks Created 3 years, 7 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: content/browser/frame_host/navigation_request.cc
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 5bf934e4b5ba66a187672cdcc8ac44cb870f24e4..94f4bb04d385cd0f59c1437a6a2f361dcb443be0 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -383,7 +383,25 @@ void NavigationRequest::BeginNavigation() {
DCHECK(state_ == NOT_STARTED || state_ == WAITING_FOR_RENDERER_RESPONSE);
TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationRequest", this,
"BeginNavigation");
+
state_ = STARTED;
+
+ // Check Content Security Policy before the NavigationThrottles run. This is
+ // so that the CSP should be allowed to modify the request such that the
+ // navigation throttles allow, but would block it otherwise. For the same
nasko 2017/06/05 20:46:29 I'm finding this sentence a bit hard to parse, but
estark 2017/06/06 00:38:02 Reworded, hopefully better now
nasko 2017/06/06 01:03:44 Much better! Thanks! Can you also use the same wor
estark 2017/06/06 19:22:15 Done.
+ // reason, the navigation handle is created afterwards -- so that it gets the
nasko 2017/06/05 20:46:29 nit: s/navigation handle/NavigationHande/
estark 2017/06/06 00:38:02 Done.
+ // request URL after potentially being modified by CSP.
+ if (CheckContentSecurityPolicyFrameSrc(false /* is redirect */) ==
+ CONTENT_SECURITY_POLICY_CHECK_FAILED) {
+ // Create a navigation handle so that the correct error code can be set on
+ // it by OnRequestFailed().
+ CreateNavigationHandle();
+ OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT);
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
nasko 2017/06/05 20:46:29 nit: empty line before the comment.
estark 2017/06/06 00:38:02 Done.
+ // destroyed the NavigationRequest.
+ return;
+ }
+
CreateNavigationHandle();
RenderFrameDevToolsAgentHost::OnBeforeNavigation(navigation_handle_.get());
@@ -508,6 +526,17 @@ void NavigationRequest::OnRequestRedirected(
common_params_.referrer =
Referrer::SanitizeForRequest(common_params_.url, common_params_.referrer);
+ // Check Content Security Policy before the NavigationThrottles run. This is
+ // so that the CSP should be allowed to modify the request such that the
+ // navigation throttles allow, but would block it otherwise.
+ if (CheckContentSecurityPolicyFrameSrc(true /* is redirect */) ==
+ CONTENT_SECURITY_POLICY_CHECK_FAILED) {
+ OnRequestFailed(false, net::ERR_BLOCKED_BY_CLIENT);
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
nasko 2017/06/05 20:46:30 nit: an empty line before the comment.
estark 2017/06/06 00:38:02 Done.
+ // destroyed the NavigationRequest.
+ return;
+ }
+
// For non browser initiated navigations we need to check if the source has
// access to the URL. We always allow browser initiated requests.
// TODO(clamy): Kill the renderer if FilterURL fails?
@@ -894,4 +923,33 @@ void NavigationRequest::CommitNavigation() {
frame_tree_node_->ResetNavigationRequest(true, true);
}
+NavigationRequest::ContentSecurityPolicyCheckResult
+NavigationRequest::CheckContentSecurityPolicyFrameSrc(bool is_redirect) {
+ if (common_params_.url.SchemeIs(url::kAboutScheme))
+ return CONTENT_SECURITY_POLICY_CHECK_PASSED;
+
+ if (common_params_.should_check_main_world_csp ==
+ CSPDisposition::DO_NOT_CHECK)
nasko 2017/06/05 20:46:29 nit: two line if statement needs {}.
estark 2017/06/06 00:38:02 Done.
+ return CONTENT_SECURITY_POLICY_CHECK_PASSED;
+
+ // The CSP frame-src directive only applies to subframes.
+ if (frame_tree_node()->IsMainFrame())
+ return CONTENT_SECURITY_POLICY_CHECK_PASSED;
+
+ FrameTreeNode* parent_ftn = frame_tree_node()->parent();
+ DCHECK(parent_ftn);
+ RenderFrameHostImpl* parent = parent_ftn->current_frame_host();
+ DCHECK(parent);
+
+ SourceLocation source_location;
+ if (common_params_.source_location)
+ source_location = common_params_.source_location.value();
+ if (parent->IsAllowedByCsp(CSPDirective::FrameSrc, common_params_.url,
+ is_redirect, source_location)) {
nasko 2017/06/05 20:46:29 Can't we just pass in common_params_.source_locati
estark 2017/06/06 00:38:03 Changed to value_or
nasko 2017/06/06 01:03:44 Nice! TIL about value_or and the code does look ni
+ return CONTENT_SECURITY_POLICY_CHECK_PASSED;
+ }
+
+ return CONTENT_SECURITY_POLICY_CHECK_FAILED;
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698