| 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 |