OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/frame_host/mixed_content_navigation_throttle.h" | 5 #include "content/browser/frame_host/mixed_content_navigation_throttle.h" |
6 | 6 |
7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "content/browser/frame_host/frame_tree.h" | 9 #include "content/browser/frame_host/frame_tree.h" |
10 #include "content/browser/frame_host/frame_tree_node.h" | 10 #include "content/browser/frame_host/frame_tree_node.h" |
11 #include "content/browser/frame_host/navigation_handle_impl.h" | 11 #include "content/browser/frame_host/navigation_handle_impl.h" |
12 #include "content/browser/frame_host/render_frame_host_delegate.h" | 12 #include "content/browser/frame_host/render_frame_host_delegate.h" |
13 #include "content/browser/renderer_host/render_view_host_impl.h" | 13 #include "content/browser/renderer_host/render_view_host_impl.h" |
14 #include "content/common/frame_messages.h" | 14 #include "content/common/frame_messages.h" |
15 #include "content/public/browser/content_browser_client.h" | 15 #include "content/public/browser/content_browser_client.h" |
16 #include "content/public/browser/render_frame_host.h" | 16 #include "content/public/browser/render_frame_host.h" |
17 #include "content/public/common/browser_side_navigation_policy.h" | 17 #include "content/public/common/browser_side_navigation_policy.h" |
18 #include "content/public/common/content_client.h" | 18 #include "content/public/common/content_client.h" |
19 #include "content/public/common/origin_util.h" | 19 #include "content/public/common/origin_util.h" |
20 #include "content/public/common/web_preferences.h" | 20 #include "content/public/common/web_preferences.h" |
21 #include "net/base/url_util.h" | 21 #include "net/base/url_util.h" |
22 #include "url/gurl.h" | 22 #include "url/gurl.h" |
23 #include "url/origin.h" | 23 #include "url/origin.h" |
24 #include "url/url_constants.h" | 24 #include "url/url_constants.h" |
25 #include "url/url_util.h" | 25 #include "url/url_util.h" |
26 | 26 |
| 27 namespace content { |
| 28 |
27 namespace { | 29 namespace { |
28 | 30 |
29 using namespace content; | |
30 | |
31 // Should return the same value as SchemeRegistry::shouldTreatURLSchemeAsSecure. | 31 // Should return the same value as SchemeRegistry::shouldTreatURLSchemeAsSecure. |
32 bool IsSecureScheme(const std::string& scheme) { | 32 bool IsSecureScheme(const std::string& scheme) { |
33 return base::ContainsValue(url::GetSecureSchemes(), scheme); | 33 return base::ContainsValue(url::GetSecureSchemes(), scheme); |
34 } | 34 } |
35 | 35 |
36 // Should return the same value as SecurityOrigin::isLocal and | 36 // Should return the same value as SecurityOrigin::isLocal and |
37 // SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled. | 37 // SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled. |
38 bool ShouldTreatURLSchemeAsCORSEnabled(const GURL& url) { | 38 bool ShouldTreatURLSchemeAsCORSEnabled(const GURL& url) { |
39 return base::ContainsValue(url::GetCORSEnabledSchemes(), url.scheme()); | 39 return base::ContainsValue(url::GetCORSEnabledSchemes(), url.scheme()); |
40 } | 40 } |
41 | 41 |
42 // Should return the same value as SecurityOrigin::isSecure. | 42 // Should return the same value as SecurityOrigin::isSecure. |
43 // TODO(carlosk): secure origin checks don't match between content and Blink | 43 // TODO(carlosk): secure origin checks don't match between content and Blink |
44 // hence this implementation here instead of a direct call to IsOriginSecure (in | 44 // hence this implementation here instead of a direct call to |
45 // origin_util.cc). See https://crbug.com/629059. | 45 // content::IsOriginSecure (in origin_util.cc). See https://crbug.com/629059. |
46 bool IsOriginSecure(const GURL& url) { | 46 bool IsSecureOriginForMixedContent(const GURL& url) { |
47 if (IsSecureScheme(url.scheme())) | 47 if (IsSecureScheme(url.scheme())) |
48 return true; | 48 return true; |
49 | 49 |
50 if (url.SchemeIsFileSystem() || url.SchemeIsBlob()) { | 50 if (url.SchemeIsFileSystem() || url.SchemeIsBlob()) { |
51 // Should use inner URL. | 51 // Should use inner URL. |
52 url::Origin origin(url); | 52 url::Origin origin(url); |
53 if (IsSecureScheme(origin.scheme())) | 53 if (IsSecureScheme(origin.scheme())) |
54 return true; | 54 return true; |
55 } | 55 } |
56 | 56 |
57 return IsOriginWhiteListedTrustworthy(url::Origin(url)); | 57 return IsOriginWhiteListedTrustworthy(url::Origin(url)); |
58 } | 58 } |
59 | 59 |
60 // Should return the same value as the resource URL checks assigned to | 60 // Should return the same value as the resource URL checks assigned to |
61 // |isAllowed| made inside MixedContentChecker::isMixedContent. | 61 // |isAllowed| made inside MixedContentChecker::isMixedContent. |
62 bool IsUrlPotentiallySecure(const GURL& url) { | 62 bool IsUrlPotentiallySecure(const GURL& url) { |
63 // blob: and filesystem: URLs never hit the network, and access is restricted | 63 // blob: and filesystem: URLs never hit the network, and access is restricted |
64 // to same-origin contexts, so they are not blocked. | 64 // to same-origin contexts, so they are not blocked. |
65 bool is_secure = | 65 bool is_secure = url.SchemeIs(url::kBlobScheme) || |
66 url.SchemeIs(url::kBlobScheme) || url.SchemeIs(url::kFileSystemScheme) || | 66 url.SchemeIs(url::kFileSystemScheme) || |
67 IsOriginSecure(url) || IsPotentiallyTrustworthyOrigin(url::Origin(url)); | 67 IsSecureOriginForMixedContent(url) || |
| 68 IsPotentiallyTrustworthyOrigin(url::Origin(url)); |
68 | 69 |
69 // TODO(mkwst): Remove this once the following draft is implemented: | 70 // TODO(mkwst): Remove this once the following draft is implemented: |
70 // https://tools.ietf.org/html/draft-west-let-localhost-be-localhost-03. See: | 71 // https://tools.ietf.org/html/draft-west-let-localhost-be-localhost-03. See: |
71 // https://crbug.com/691930. | 72 // https://crbug.com/691930. |
72 if (is_secure && url.SchemeIs(url::kHttpScheme) && | 73 if (is_secure && url.SchemeIs(url::kHttpScheme) && |
73 net::IsLocalHostname(url.HostNoBrackets(), nullptr)) { | 74 net::IsLocalHostname(url.HostNoBrackets(), nullptr)) { |
74 is_secure = false; | 75 is_secure = false; |
75 } | 76 } |
76 | 77 |
77 return is_secure; | 78 return is_secure; |
(...skipping 22 matching lines...) Expand all Loading... |
100 params.request_context_type = navigation_handle->request_context_type(); | 101 params.request_context_type = navigation_handle->request_context_type(); |
101 params.was_allowed = was_allowed; | 102 params.was_allowed = was_allowed; |
102 params.had_redirect = for_redirect; | 103 params.had_redirect = for_redirect; |
103 params.source_location = navigation_handle->source_location(); | 104 params.source_location = navigation_handle->source_location(); |
104 | 105 |
105 rfh->Send(new FrameMsg_MixedContentFound(rfh->GetRoutingID(), params)); | 106 rfh->Send(new FrameMsg_MixedContentFound(rfh->GetRoutingID(), params)); |
106 } | 107 } |
107 | 108 |
108 } // namespace | 109 } // namespace |
109 | 110 |
110 namespace content { | |
111 | |
112 // static | 111 // static |
113 std::unique_ptr<NavigationThrottle> | 112 std::unique_ptr<NavigationThrottle> |
114 MixedContentNavigationThrottle::CreateThrottleForNavigation( | 113 MixedContentNavigationThrottle::CreateThrottleForNavigation( |
115 NavigationHandle* navigation_handle) { | 114 NavigationHandle* navigation_handle) { |
116 if (IsBrowserSideNavigationEnabled()) | 115 if (IsBrowserSideNavigationEnabled()) |
117 return base::WrapUnique( | 116 return base::WrapUnique( |
118 new MixedContentNavigationThrottle(navigation_handle)); | 117 new MixedContentNavigationThrottle(navigation_handle)); |
119 return nullptr; | 118 return nullptr; |
120 } | 119 } |
121 | 120 |
122 MixedContentNavigationThrottle::MixedContentNavigationThrottle( | 121 MixedContentNavigationThrottle::MixedContentNavigationThrottle( |
123 NavigationHandle* navigation_handle) | 122 NavigationHandle* navigation_handle) |
124 : NavigationThrottle(navigation_handle) { | 123 : NavigationThrottle(navigation_handle) { |
125 DCHECK(IsBrowserSideNavigationEnabled()); | 124 DCHECK(IsBrowserSideNavigationEnabled()); |
126 } | 125 } |
127 | 126 |
128 MixedContentNavigationThrottle::~MixedContentNavigationThrottle() {} | 127 MixedContentNavigationThrottle::~MixedContentNavigationThrottle() {} |
129 | 128 |
130 ThrottleCheckResult MixedContentNavigationThrottle::WillStartRequest() { | 129 NavigationThrottle::ThrottleCheckResult |
| 130 MixedContentNavigationThrottle::WillStartRequest() { |
131 bool should_block = ShouldBlockNavigation(false); | 131 bool should_block = ShouldBlockNavigation(false); |
132 return should_block ? ThrottleCheckResult::CANCEL | 132 return should_block ? CANCEL : PROCEED; |
133 : ThrottleCheckResult::PROCEED; | |
134 } | 133 } |
135 | 134 |
136 ThrottleCheckResult MixedContentNavigationThrottle::WillRedirectRequest() { | 135 NavigationThrottle::ThrottleCheckResult |
| 136 MixedContentNavigationThrottle::WillRedirectRequest() { |
137 // Upon redirects the same checks are to be executed as for requests. | 137 // Upon redirects the same checks are to be executed as for requests. |
138 bool should_block = ShouldBlockNavigation(true); | 138 bool should_block = ShouldBlockNavigation(true); |
139 return should_block ? ThrottleCheckResult::CANCEL | 139 return should_block ? CANCEL : PROCEED; |
140 : ThrottleCheckResult::PROCEED; | |
141 } | 140 } |
142 | 141 |
143 ThrottleCheckResult MixedContentNavigationThrottle::WillProcessResponse() { | 142 NavigationThrottle::ThrottleCheckResult |
| 143 MixedContentNavigationThrottle::WillProcessResponse() { |
144 // TODO(carlosk): At this point we are about to process the request response. | 144 // TODO(carlosk): At this point we are about to process the request response. |
145 // So if we ever need to, here/now it is a good moment to check for the final | 145 // So if we ever need to, here/now it is a good moment to check for the final |
146 // attained security level of the connection. For instance, does it use an | 146 // attained security level of the connection. For instance, does it use an |
147 // outdated protocol? The implementation should be based off | 147 // outdated protocol? The implementation should be based off |
148 // MixedContentChecker::handleCertificateError. See https://crbug.com/576270. | 148 // MixedContentChecker::handleCertificateError. See https://crbug.com/576270. |
149 return ThrottleCheckResult::PROCEED; | 149 return PROCEED; |
150 } | 150 } |
151 | 151 |
152 const char* MixedContentNavigationThrottle::GetNameForLogging() { | 152 const char* MixedContentNavigationThrottle::GetNameForLogging() { |
153 return "MixedContentNavigationThrottle"; | 153 return "MixedContentNavigationThrottle"; |
154 } | 154 } |
155 | 155 |
156 // Based off of MixedContentChecker::shouldBlockFetch. | 156 // Based off of MixedContentChecker::shouldBlockFetch. |
157 bool MixedContentNavigationThrottle::ShouldBlockNavigation(bool for_redirect) { | 157 bool MixedContentNavigationThrottle::ShouldBlockNavigation(bool for_redirect) { |
158 NavigationHandleImpl* handle_impl = | 158 NavigationHandleImpl* handle_impl = |
159 static_cast<NavigationHandleImpl*>(navigation_handle()); | 159 static_cast<NavigationHandleImpl*>(navigation_handle()); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 // MixedContentChecker::inWhichFrameIs. | 287 // MixedContentChecker::inWhichFrameIs. |
288 if (mixed_content_node) { | 288 if (mixed_content_node) { |
289 // We're currently only checking for mixed content in `https://*` contexts. | 289 // We're currently only checking for mixed content in `https://*` contexts. |
290 // What about other "secure" contexts the SchemeRegistry knows about? We'll | 290 // What about other "secure" contexts the SchemeRegistry knows about? We'll |
291 // use this method to measure the occurrence of non-webby mixed content to | 291 // use this method to measure the occurrence of non-webby mixed content to |
292 // make sure we're not breaking the world without realizing it. | 292 // make sure we're not breaking the world without realizing it. |
293 if (mixed_content_node->current_origin().scheme() != url::kHttpsScheme) { | 293 if (mixed_content_node->current_origin().scheme() != url::kHttpsScheme) { |
294 mixed_content_features_.insert( | 294 mixed_content_features_.insert( |
295 MIXED_CONTENT_IN_NON_HTTPS_FRAME_THAT_RESTRICTS_MIXED_CONTENT); | 295 MIXED_CONTENT_IN_NON_HTTPS_FRAME_THAT_RESTRICTS_MIXED_CONTENT); |
296 } | 296 } |
297 } else if (!IsOriginSecure(url) && | 297 } else if (!IsSecureOriginForMixedContent(url) && |
298 (IsSecureScheme(root->current_origin().scheme()) || | 298 (IsSecureScheme(root->current_origin().scheme()) || |
299 IsSecureScheme(parent->current_origin().scheme()))) { | 299 IsSecureScheme(parent->current_origin().scheme()))) { |
300 mixed_content_features_.insert( | 300 mixed_content_features_.insert( |
301 MIXED_CONTENT_IN_SECURE_FRAME_THAT_DOES_NOT_RESTRICT_MIXED_CONTENT); | 301 MIXED_CONTENT_IN_SECURE_FRAME_THAT_DOES_NOT_RESTRICT_MIXED_CONTENT); |
302 } | 302 } |
303 return mixed_content_node; | 303 return mixed_content_node; |
304 } | 304 } |
305 | 305 |
306 void MixedContentNavigationThrottle::MaybeSendBlinkFeatureUsageReport() { | 306 void MixedContentNavigationThrottle::MaybeSendBlinkFeatureUsageReport() { |
307 if (!mixed_content_features_.empty()) { | 307 if (!mixed_content_features_.empty()) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 // static | 358 // static |
359 bool MixedContentNavigationThrottle::IsMixedContentForTesting( | 359 bool MixedContentNavigationThrottle::IsMixedContentForTesting( |
360 const GURL& origin_url, | 360 const GURL& origin_url, |
361 const GURL& url) { | 361 const GURL& url) { |
362 const url::Origin origin(origin_url); | 362 const url::Origin origin(origin_url); |
363 return !IsUrlPotentiallySecure(url) && | 363 return !IsUrlPotentiallySecure(url) && |
364 DoesOriginSchemeRestrictMixedContent(origin); | 364 DoesOriginSchemeRestrictMixedContent(origin); |
365 } | 365 } |
366 | 366 |
367 } // namespace content | 367 } // namespace content |
OLD | NEW |