Improving security in Manifest V3. Manifest V3 introduces changes aimed at enhancing extension security. This section outlines steps to bolster the security of your extensions, focusing on code not part of the extension service worker. It covers removing the execution of arbitrary strings, eliminating remotely hosted code, updating content security policies, and more. Created by Exmo – a monetization platform for browser extensions.
Previos posts:
Note: Manifest V3 is typically supported in Chrome 88 or later. For features introduced in subsequent Chrome versions, refer to the API reference documentation to verify support information. If your extension relies on a particular API, you can specify a minimum Chrome version in the manifest file.
Manifest V3 prohibits executing external logic using methods like executeScript()
, eval()
, and new Function()
. To comply with this, follow these steps:
eval()
and new Function(...)
are still supported within sandboxed iframes.Note: executeScript()
is now part of the scripting namespace instead of the tabs namespace. Refer to the Move executeScript()
guide for updating calls.
However, some exceptions allow executing arbitrary strings, such as injecting remote hosted stylesheets, using chrome.devtools.inspectWindow.eval
, and chrome.debugger.sendCommand
for debugger extensions.
Manifest V3 mandates that all extension logic must reside within the extension package. This means you cannot load and execute remotely hosted files. Common examples include JavaScript files from developer servers or libraries hosted on CDNs.
Alternative approaches include:
Refer to the guidelines for handling external libraries in tab-injected scripts and injecting functions for dynamic behavior.
Your extension can implement configuration-driven features by loading and caching a remote configuration file, such as a JSON file, during runtime. This cached configuration determines which features are enabled or disabled based on the defined settings.
Utilize a remote web service for externalized logic in your extension. By calling a remote web service, you can keep sensitive code private and easily modify it as needed without the hassle of resubmitting to the Chrome Web Store. This approach minimizes the overhead associated with managing code changes.
Remotely hosted code can be embedded within sandboxed iframes in your extension. However, it’s important to note that this method may not work if the embedded code requires access to the embedding page’s Document Object Model (DOM). Sandboxed iframes provide a secure environment for executing remotely hosted code while isolating it from the main page’s DOM.
If your extension relies on third-party libraries, consider bundling them locally instead of loading them from external servers. For popular frameworks like React or Bootstrap, download the minified files and include them directly in your extension project. By importing these libraries locally, you reduce dependency on external servers and ensure consistent availability of resources. For example:
<script src="./react-dom.production.min.js"></script>
<link href="./bootstrap.min.css" rel="stylesheet">
To include a library in a service worker, configure the “background.type” key in the manifest file to “module” and utilize an import statement.
Caution: Certain libraries, such as Firebase, may dynamically fetch additional code at runtime. To address this, you have two options. First, opt for a library that does not rely on remotely-hosted code. Alternatively, you can download all potential dynamic imports during the build process. Below is an example script demonstrating how to bundle Firebase using Rollup.js.
You can still load external libraries dynamically in tab-injected scripts by including them in the files array when using scripting.executeScript(). This allows you to load data remotely at runtime.
chrome.scripting.executeScript({
target: {tabId: tab.id},
files: ['jquery-min.js', 'content-script.js']
});
To inject greater dynamism, you can utilize the func property within scripting.executeScript()
to inject a function as a content script and pass variables using the args property.
Manifest V2
let name = 'World!';
chrome.tabs.executeScript({
code: `alert('Hello, ${name}!')`
});
In a background script file.
Manifest V3
async function getCurrentTab() {/* ... */}
let tab = await getCurrentTab();
function showAlert(givenName) {
alert(`Hello, ${givenName}`);
}
let name = 'World';
chrome.scripting.executeScript({
target: {tabId: tab.id},
func: showAlert,
args: [name],
});
In the background service worker.
You can explore a function injection example available in the Chrome Extension Samples repository. Additionally, you can find a reference for the getCurrentTab()
function.
If the aforementioned methods don’t address your specific use case, you may need to explore alternative solutions. This could involve migrating to a different library that better suits your needs or finding alternative ways to leverage the functionality of the existing library. For instance, in the case of Google Analytics, you might consider switching to the Google Measurement Protocol instead of relying on the official remotely-hosted JavaScript version, as detailed in our Google Analytics 4 guide.
The “content_security_policy
” remains a part of the manifest.json file in Manifest V3, but it is now structured as a dictionary supporting two properties: “extension_pages
” and “sandbox“.
In Manifest V2, it was typically defined as follows:
{
...
"content_security_policy": "default-src 'self'"
...
}
In Manifest V3, it is structured like this:
{
...
"content_security_policy": {
"extension_pages": "default-src 'self'",
"sandbox": "..."
}
...
}
The “extension_pages
” property refers to contexts within your extension, such as HTML files and service workers.
Note: These page types are served from the chrome-extension:// protocol. For example, a page in your extension would be accessed via chrome-extension://EXTENSION_ID/foo.html.
sandbox: Applies to any sandboxed extension pages used by your extension.
Manifest V3 disallows certain content security policy values in the “extension_pages” field that were permitted in Manifest V2, specifically those that allow remote code execution. The script-src, object-src, and worker-src directives are limited to the following values:
Note that content security policy values for sandbox do not have these new restrictions.
Manifest V3 introduces stricter security measures to mitigate potential risks and enhance user privacy and safety. By adhering to these security standards, developers can create more secure extensions that protect user data and ensure a safer browsing experience.
Manifest V3 prohibits executing external logic using methods like executeScript(), eval(), and new Function(). It also mandates that all extension logic must reside within the extension package, disallowing the loading and execution of remotely hosted files. Additionally, Manifest V3 introduces updates to content security policies to further enhance security.
To comply with Manifest V3 requirements, developers should move all external code into the extension bundle, update script and style references to load resources from the bundle, and utilize chrome.runtime.getURL() to build resource URLs at runtime. Additionally, consider using sandboxed iframes where necessary.
Instead of loading remotely hosted code, developers can implement configuration-driven features and logic, utilize externalized logic with a remote service, embed remotely hosted code in sandboxed iframes, or bundle third-party libraries locally. These approaches ensure that all extension logic resides within the extension package, enhancing security.
In Manifest V3, developers should update the content security policy by structuring it as a dictionary with properties for “extension_pages” and “sandbox”. It’s important to remove unsupported content security policy values that allow remote code execution and ensure that only permitted values are used to maintain security standards.
You’ve spent tons of time on your extension: optimized the code, squashed bugs, polished the…
In the browser extension development community, particularly among Firefox users, there is a bias against…
Affiliate marketing is a powerful tool for monetizing browser extensions. It requires no direct costs…
Your browser extension already delivers value to users, but have you considered making it a…
Creating a successful extension is a significant achievement, but one of the toughest challenges begins…
Developers looking for innovative ways to generate revenue can turn to Affiliate Marketing to Monetize…
This website uses cookies to enhance your browsing experience. By continuing to use our site, you consent to our use of cookies.
Terms and Conditions