url_request_util.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "extensions/browser/url_request_util.h"
  5. #include <string>
  6. #include "base/strings/string_piece.h"
  7. #include "extensions/browser/extension_navigation_ui_data.h"
  8. #include "extensions/browser/extensions_browser_client.h"
  9. #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
  10. #include "extensions/browser/process_map.h"
  11. #include "extensions/common/extension.h"
  12. #include "extensions/common/extension_set.h"
  13. #include "extensions/common/manifest_handlers/icons_handler.h"
  14. #include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
  15. #include "extensions/common/manifest_handlers/webview_info.h"
  16. #include "services/network/public/cpp/request_destination.h"
  17. #include "services/network/public/cpp/resource_request.h"
  18. #include "third_party/blink/public/common/loader/resource_type_util.h"
  19. namespace extensions {
  20. namespace url_request_util {
  21. bool AllowCrossRendererResourceLoad(
  22. const network::ResourceRequest& request,
  23. network::mojom::RequestDestination destination,
  24. ui::PageTransition page_transition,
  25. int child_id,
  26. bool is_incognito,
  27. const Extension* extension,
  28. const ExtensionSet& extensions,
  29. const ProcessMap& process_map,
  30. bool* allowed) {
  31. const GURL& url = request.url;
  32. base::StringPiece resource_path = url.path_piece();
  33. // This logic is performed for main frame requests in
  34. // ExtensionNavigationThrottle::WillStartRequest.
  35. if (child_id != -1 ||
  36. destination != network::mojom::RequestDestination::kDocument) {
  37. // Extensions with webview: allow loading certain resources by guest
  38. // renderers with privileged partition IDs as specified in owner's extension
  39. // the manifest file.
  40. std::string owner_extension_id;
  41. int owner_process_id;
  42. WebViewRendererState::GetInstance()->GetOwnerInfo(
  43. child_id, &owner_process_id, &owner_extension_id);
  44. const Extension* owner_extension = extensions.GetByID(owner_extension_id);
  45. std::string partition_id;
  46. bool is_guest = WebViewRendererState::GetInstance()->GetPartitionID(
  47. child_id, &partition_id);
  48. if (AllowCrossRendererResourceLoadHelper(
  49. is_guest, extension, owner_extension, partition_id, resource_path,
  50. page_transition, allowed)) {
  51. return true;
  52. }
  53. }
  54. // The following checks require that we have an actual extension object. If we
  55. // don't have it, allow the request handling to continue with the rest of the
  56. // checks.
  57. if (!extension) {
  58. *allowed = true;
  59. return true;
  60. }
  61. // Disallow loading of packaged resources for hosted apps. We don't allow
  62. // hybrid hosted/packaged apps. The one exception is access to icons, since
  63. // some extensions want to be able to do things like create their own
  64. // launchers.
  65. base::StringPiece resource_root_relative_path =
  66. url.path_piece().empty() ? base::StringPiece()
  67. : url.path_piece().substr(1);
  68. if (extension->is_hosted_app() &&
  69. !IconsInfo::GetIcons(extension)
  70. .ContainsPath(resource_root_relative_path)) {
  71. LOG(ERROR) << "Denying load of " << url.spec() << " from hosted app.";
  72. *allowed = false;
  73. return true;
  74. }
  75. DCHECK_EQ(extension->url(), url.GetWithEmptyPath());
  76. // Navigating the main frame to an extension URL is allowed, even if not
  77. // explicitly listed as web_accessible_resource.
  78. if (destination == network::mojom::RequestDestination::kDocument) {
  79. *allowed = true;
  80. return true;
  81. }
  82. // When navigating in subframe, allow if it is the same origin
  83. // as the top-level frame. This can only be the case if the subframe
  84. // request is coming from the extension process.
  85. if (network::IsRequestDestinationEmbeddedFrame(destination) &&
  86. process_map.Contains(child_id)) {
  87. *allowed = true;
  88. return true;
  89. }
  90. // Allow web accessible extension resources to be loaded as
  91. // subresources/sub-frames.
  92. if (WebAccessibleResourcesInfo::IsResourceWebAccessible(
  93. extension, std::string(resource_path), request.request_initiator)) {
  94. *allowed = true;
  95. return true;
  96. }
  97. if (!ui::PageTransitionIsWebTriggerable(page_transition)) {
  98. *allowed = false;
  99. return true;
  100. }
  101. // Couldn't determine if the resource is allowed or not.
  102. return false;
  103. }
  104. bool AllowCrossRendererResourceLoadHelper(bool is_guest,
  105. const Extension* extension,
  106. const Extension* owner_extension,
  107. const std::string& partition_id,
  108. base::StringPiece resource_path,
  109. ui::PageTransition page_transition,
  110. bool* allowed) {
  111. if (is_guest) {
  112. // An extension's resources should only be accessible to WebViews owned by
  113. // that extension.
  114. if (owner_extension != extension) {
  115. *allowed = false;
  116. return true;
  117. }
  118. *allowed = WebviewInfo::IsResourceWebviewAccessible(
  119. extension, partition_id, std::string(resource_path));
  120. return true;
  121. }
  122. return false;
  123. }
  124. } // namespace url_request_util
  125. } // namespace extensions