content_script_tracker.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2021 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. #ifndef EXTENSIONS_BROWSER_CONTENT_SCRIPT_TRACKER_H_
  5. #define EXTENSIONS_BROWSER_CONTENT_SCRIPT_TRACKER_H_
  6. #include "base/types/pass_key.h"
  7. #include "extensions/common/extension_id.h"
  8. #include "extensions/common/mojom/host_id.mojom-forward.h"
  9. #include "url/gurl.h"
  10. struct HostID;
  11. namespace content {
  12. class NavigationHandle;
  13. class RenderFrameHost;
  14. class RenderProcessHost;
  15. } // namespace content
  16. namespace extensions {
  17. class Extension;
  18. class ExtensionWebContentsObserver;
  19. class UserScriptLoader;
  20. class RequestContentScript;
  21. class ScriptExecutor;
  22. // Class for
  23. // 1) observing when a content script gets injected into a process,
  24. // 2) checking if a content script was ever injected into a given process.
  25. //
  26. // WARNING: False positives might happen. This class is primarily meant to help
  27. // make security decisions. This focus means that it is known and
  28. // working-as-intended that false positives might happen - in some scenarios the
  29. // tracker might report that a content script was injected, when it actually
  30. // wasn't (e.g. because the tracker might not have access to all the
  31. // renderer-side information used to decide whether to run a content script).
  32. //
  33. // WARNING: This class ignores cases that don't currently need IPC verification:
  34. // - CSS content scripts (only JavaScript content scripts are tracked)
  35. // - WebUI content scripts (only content scripts injected by extensions are
  36. // tracked)
  37. //
  38. // This class may only be used on the UI thread.
  39. class ContentScriptTracker {
  40. public:
  41. // Only static methods.
  42. ContentScriptTracker() = delete;
  43. // Answers whether the `process` has ever in the past run a content script
  44. // from an extension with the given `extension_id`.
  45. static bool DidProcessRunContentScriptFromExtension(
  46. const content::RenderProcessHost& process,
  47. const ExtensionId& extension_id);
  48. // Returns all the IDs for extensions that have ever in the past run a content
  49. // script in `process`.
  50. static ExtensionIdSet GetExtensionsThatRanScriptsInProcess(
  51. const content::RenderProcessHost& process);
  52. // The few methods below are called by ExtensionWebContentsObserver to notify
  53. // ContentScriptTracker about various events. The methods correspond directly
  54. // to methods of content::WebContentsObserver with the same names.
  55. static void ReadyToCommitNavigation(
  56. base::PassKey<ExtensionWebContentsObserver> pass_key,
  57. content::NavigationHandle* navigation);
  58. static void DidFinishNavigation(
  59. base::PassKey<ExtensionWebContentsObserver> pass_key,
  60. content::NavigationHandle* navigation);
  61. static void RenderFrameCreated(
  62. base::PassKey<ExtensionWebContentsObserver> pass_key,
  63. content::RenderFrameHost* frame);
  64. static void RenderFrameDeleted(
  65. base::PassKey<ExtensionWebContentsObserver> pass_key,
  66. content::RenderFrameHost* frame);
  67. // Called before ExtensionMsg_ExecuteCode is sent to a renderer process
  68. // (typically when handling chrome.tabs.executeScript or a similar API call).
  69. //
  70. // The caller needs to ensure that if `host_id.type() == HostID::EXTENSIONS`,
  71. // then the extension with the given `host_id` exists and is enabled.
  72. static void WillExecuteCode(base::PassKey<ScriptExecutor> pass_key,
  73. content::RenderFrameHost* frame,
  74. const mojom::HostID& host_id);
  75. // Called before `extensions::mojom::LocalFrame::ExecuteDeclarativeScript` is
  76. // invoked in a renderer process (e.g. when handling RequestContentScript
  77. // action of the `chrome.declarativeContent` API).
  78. static void WillExecuteCode(base::PassKey<RequestContentScript> pass_key,
  79. content::RenderFrameHost* frame,
  80. const Extension& extension);
  81. // Called before the given renderer `process` is notified about new content
  82. // scripts.
  83. static void WillUpdateContentScriptsInRenderer(
  84. base::PassKey<UserScriptLoader> pass_key,
  85. const mojom::HostID& host_id,
  86. content::RenderProcessHost& process);
  87. private:
  88. using PassKey = base::PassKey<ContentScriptTracker>;
  89. // See the doc comment of DoContentScriptsMatch in the .cc file.
  90. friend class ContentScriptMatchingBrowserTest;
  91. static bool DoContentScriptsMatchForTesting(const Extension& extension,
  92. content::RenderFrameHost* frame,
  93. const GURL& url);
  94. };
  95. } // namespace extensions
  96. #endif // EXTENSIONS_BROWSER_CONTENT_SCRIPT_TRACKER_H_