Prevent SDK initialization via `Sentry.init` in Chrome extension
Problem Statement
From time to time we get reports about browser extensions using Sentry with global handler integrations installed. The consequences are that the extension SDK collides with an SDK being used in the page, producing unwanted side effects like:
- event leakage from page to extension or vice versa
- SDK version discrepancies leading to type errors
Solution Brainstorm
There is a way to detect if code is being executed within a Chrome extension. Let's add this check in the browser SDK's init function and, in case of detecting usage in an extension, stop initialization with a warning that extension authors should only directly use the SDK client instead of the global init.
Additional Considerations:
- Up for discussion: We could export a dedicated init function (e.g.
Sentry.initForExtension()) that only sets up a minimal SDK setup without global handlers, etc. This, however, is out of scope for the initial task.
I would not do initForExtension instead, write better docs how to work around it in case anyone really needs it
function init() {
.....
if (chrome.extension) {
console.error('We do not recommend running Sentry this way in an extension, check: https://docs.sentry.io/platforms/javascript/guides/react/troubleshooting/#setting-up-sentry-in-shared-environments-eg-browser-extensions');
return;
}
Yeah, we can list it as a "nice to have" feature. Fwiw, I think it'd make sense to create an init method that generally inits the SDKs in a minimal (more or less isolated) way. Not just for extensions but maybe also for MFEs or 3rd party plugins. Such a function needs more considerations though, so I agree, it's out of scope for this specific task. Updated the description accordingly.
Does running Sentry.init() in content scripts which are in an "isolated" world (https://developer.chrome.com/docs/extensions/reference/api/scripting#type-ExecutionWorld) also cause issues? Or is it only a problem in the "main" world?
I understand of course why we don't want extensions to run Sentry.init() in the same JS context as the main page. This would pollute and confuse the page, especially if it has an existing Sentry instance.
As of Chrome Extensions with Manifest Version 3 (MV3), there are 2 options for where content scripts run: "main" (shared with the page's JS) and "isolated" (an entirely separate JS context which should be unable to affect the main page). I'm not sure if older MV2 extensions maybe defaulted to the "main" world, and caused problems?
I'm not sure how running Sentry.init() from a content script in "isolated" world could cause problems.
Right now I can cheat and evade https://github.com/getsentry/sentry-javascript/pull/10844, but am curious if I shouldn't be doing that.
Also, if Sentry.init() is unsafe in "main" world but safe in "isolated" world, you may want to change #10844 so you can have better Extensions support
@jaredp Thanks for pointing this out! Looks like this should be possible if the script is running in the isolated world. We will investigate and test this with MV3 and update the PR + docs.
@jaredp Out of interest, how are you cheating this? I know I am running in the isolated world and would still like to use Sentry.