# How to avoid "Access your data for all websites" permission

**URL:** <https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370>\
**Category:** Add-on Support\
**Created:** [March 14, 2025, 5:10pm UTC](https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370 "2025-03-14T17:10:38Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![bluelemon](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/bluelemon/32/77685_2.png) [@bluelemon](https://discourse.mozilla.org/u/bluelemon)\
**Post date:** [March 14, 2025, 5:10pm UTC](https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370/1 "2025-03-14T17:10:38Z")

</div>

If I were a user, this kind of permission would make me think twice about using an extension, especially if it means that the extension has access to my credentials for any website, including banking websites!

I’m wondering if this permission (in the case of an extension for mv3) is determined by the “host\_permissions”, because an extension could just as well use a listener for keyup, keydown or keypress events to capture a user’s credentials (I guess) and in the same time restrict the host permissions to known payment websites to avoid the “Access your data for all websites”.

I think that it’s becoming more and more important for Mozilla to screen extensions for security to build trust. I’d strongly encourage Mozilla to introduce at least 2 levels of security rating:

A → the extension has been thoroughly reviewed by Mozilla staff and meets a high level of security  
C → the extension has been tested by AI for security and offers a satisfactory level of security

Alternatively, Mozilla could introduce a"Security report" button for each extenssion on AMO generated by AI and detailing what an extension can do and potential security loopholes.

---

<div class="post-metadata">

**Author:** ![dotproto](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/dotproto/32/62957_2.png) [@dotproto](https://discourse.mozilla.org/u/dotproto)\
**Post date:** [March 14, 2025, 7:25pm UTC](https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370/2 "2025-03-14T19:25:21Z")

</div>

As @juraj.masiar noted [in a reply on another thread](https://discourse.mozilla.org/t/users-worried-about-block-content-on-any-page-permission/141337/4), the “Access your data for all websites” message is displayed as a result of requesting `"<all_urls>"` or other broad host permission patterns (e.g. `*://*/*`). Similarly, Chrome uses the string “Read and change all your data on all websites”. Safari uses a slightly different model for host permissions, where the default flow has users give out timed grants to specific hosts, but in that flow they use a message that conveys the same basic idea.

 ![image](https://us1.discourse-cdn.com/flex001/uploads/mozilla/original/3X/1/1/11dc865c1964c544e81c56d86fb7587a160d453c.jpeg)  
_Image via [Grammarly Support](https://support.grammarly.com/hc/en-us/articles/20888320537485-Grammarly-for-Safari-doesn-t-appear-on-a-website)_

The main alternative is to use the `activeTab` permission to grant access in response to a user invocation such as clicking the browser action, selecting a context menu entry, or triggering a keyboard shortcut. The main disadvantage of using `activeTab` is that your extension can’t passively take action on behalf of the user – the user has to consciously trigger the extension when they want it to do something.

`activeTab` can also be combined with declaring `<all_urls>` as an optional host permission in the extension’s manifest. This makes it possible for an extension to detect that the user has invoked the extension multiple times on the same website and to ask the user if they would like to give the extension access to that site via [`permissions.request`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions/request).

Thanks for your suggestions on improvements to the AMO experience. I’ll pass this along to the team for consideration.

---

<div class="post-metadata">

**Author:** ![bluelemon](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/bluelemon/32/77685_2.png) [@bluelemon](https://discourse.mozilla.org/u/bluelemon)\
**Post date:** [March 14, 2025, 7:38pm UTC](https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370/3 "2025-03-14T19:38:55Z")

</div>

Hi Simeon, thank you for your answers. I must admit I really like the way Safari handles things! It might be missing just the option to “Allow One Time”.

Unfortunately, combining `activeTab` with `<all_urls>` as an optional host permission won’t get rid of the “Access your data for all websites” permission. I think that the “…for all websites” isn’t the most worrying part, but rather “…your data…” as it doesn’t say much about the kind of data concerned (a user’s search engines isn’t as critical as a user’s credentials).

In host permissions, it would be interesting to exclude any website that deals with financial transactions, but I guess that would require a standard to make them easily identifiable.

Alternatively, if there was a way of identifying if a user is logged in a website or not, a conditional permission could allow access to a website if a user is logged in. This way a user would be able to safely input his or her credentials, during which time the extension wouldn’t have access. Then, once logged in, the extension would have access.

---

<div class="post-metadata">

**Author:** ![kg\_13](https://avatars.discourse-cdn.com/v4/letter/k/b5ac83/32.png) [@kg\_13](https://discourse.mozilla.org/u/kg_13)\
**Post date:** [March 14, 2025, 9:02pm UTC](https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370/4 "2025-03-14T21:02:15Z")

</div>

Even if you move “\<all\_urls\>” to an optional permission, ‘Access your data for all websites’ will still be requested on extension installation because you have ‘http…’ and “https…” under “content\_scripts”. Since you have an MV3 extension, all host permissions can be deactivated by a user in the about:addons page in an extensions ‘Permissions’ section. A user can then grant permissions to individual sites through the extensions toolbar button. The permissions may be temporary or permanent.

---

<div class="post-metadata">

**Author:** ![dotproto](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/dotproto/32/62957_2.png) [@dotproto](https://discourse.mozilla.org/u/dotproto)\
**Post date:** [March 17, 2025, 2:07am UTC](https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370/5 "2025-03-17T02:07:30Z")

</div>

Ah, I forgot to talk about how `activeTab` and `content_scripts` interact. Thanks for calling that out, @kg_13.

As @kg_13 suggested, any `matches` patterns that appear in the `content_scripts` declaration in your manifest.json will be included in the list of permission messages at install-time. There’s currently no way to statically declare your content script in the manifest and only have it run on hosts declared in `optional_host_permissions` that the user has granted to the extension.

If you only want your extension to run content scripts on an optional host, you would need to use [`scripting.registerContentScripts`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/registerContentScripts) to dynamically. Match patterns in dynamic content scripts are evaluated against the extension’s current host permissions grants. As a result, if you register a dynamic content script that matches `<all_urls>` it will only be injected on pages where the user has granted the extension persistent access.

> **Example extension**
>
> **manifest.json**
> 
> ```auto
> {
> "name": "Dynamic content scripts",
> "version": "0.1",
> "manifest_version": 3,
> "permissions": ["scripting"],
> "optional_host_permissions": ["<all_urls>"],
> "background": {
> "scripts": ["background.js"]
> }
> }
> 
> ```
> 
> **background.js**
> 
> ```auto
> browser.runtime.onInstalled.addListener(async () => {
> const oldScripts = await browser.scripting.getRegisteredContentScripts();
> if (oldScripts.length > 0) {
> const ids = oldScripts.map(script => script.id)
> await browser.scripting.unregisterContentScripts({ids});
> }
> 
> browser.scripting.registerContentScripts([{
> id: "content",
> js: ["content.js"],
> matches: ["<all_urls>"],
> }]);
> });
> 
> ```
> 
> **content.js**
> 
> ```auto
> alert("hello :)");
> 
> ```

---

<div class="post-metadata">

**Author:** ![bluelemon](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/bluelemon/32/77685_2.png) [@bluelemon](https://discourse.mozilla.org/u/bluelemon)\
**Post date:** [March 17, 2025, 11:26am UTC](https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370/6 "2025-03-17T11:26:16Z")

</div>

Shouldn’t the condition be `oldScripts.length > 0` instead of `oldScripts.length === 0` ? I understand that you want to unregister ‘old’ scripts. Not sure why though!

Anyway, I had used:

```auto
    "optional_host_permissions": [
        "<all_urls>"
    ],

```

which meant that the permission “Access your data for all web sites” would be optional and could be turned off.

 ![Screenshot 2025-03-17 at 12.15.36](https://us1.discourse-cdn.com/flex001/uploads/mozilla/original/3X/3/c/3c6781d90e310b0f09c85ea39caa650c2a762774.png)

However, turning it off breaks an essential feature of the extension as the latest text selection on a web page (which is stored in the extension’s local storage) is no longer accessible and can’t be used to present search results. So, I think that it’s a better practice here to use:

```auto
    "host_permissions": [
        "<all_urls>"
    ],

```

even though users could get the wrong idea and think that their data privacy isn’t being respected!

Also, I don’t think that many users are aware of the possibility to grant (optional) permission on a website basis by clicking an extension’s icon.

 ![Screenshot 2025-03-17 at 12.45.52](https://us1.discourse-cdn.com/flex001/uploads/mozilla/original/3X/c/7/c707ebb13a03d5a0025edda41b2b15b97c501f3c.png)

---

<div class="post-metadata">

**Author:** ![dotproto](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/dotproto/32/62957_2.png) [@dotproto](https://discourse.mozilla.org/u/dotproto)\
**Post date:** [March 17, 2025, 4:10pm UTC](https://discourse.mozilla.org/t/how-to-avoid-access-your-data-for-all-websites-permission/141370/7 "2025-03-17T16:10:58Z")

</div>

> [@bluelemon](#):
>
> Shouldn’t the condition be `oldScripts.length > 0` instead of `oldScripts.length === 0` ? I understand that you want to unregister ‘old’ scripts. Not sure why though!

D’oh! You’re right. Thanks for catching that bug. I’ve edited my last comment to fix the bug.

We’re removing old dynamic scripts because if you try to register an ID that already exists, the registration call will throw. Similarly, if you try to update an ID that isn’t registered the update call will throw. I figured the most reliable way to handle this was to to always remove all previous scripts and to always register the intended scripts at extension install or update.

> [@bluelemon](#):
>
> Anyway, I had used:
> 
> ```auto
> "optional_host_permissions": [
> "<all_urls>"
> ],
> 
> ```
> 
> which meant that the permission “Access your data for all web sites” would be optional and could be turned off.

In Manifest V3 all host permissions can be disabled. Even if you declare `"host_permissions": ["<all_urls>"]` in your manifest, the user can still go into the extension’s settings and disable that access level.

> [@bluelemon](#):
>
> However, turning it off breaks an essential feature of the extension as the latest text selection on a web page (which is stored in the extension’s local storage) is no longer accessible and can’t be used to present search results.

Right. Sorry, I think I may not have been clear when I first brought this up: changing the extension to use `activeTab` + `optional_host_permissions` is fundamentally different from your current approach. Its not necessarily better or worse, but it is different, so it’s best to understand the tradeoffs. It may not be the right approach for what you want to build.
