Closed Bug 1965552 Opened 3 months ago Closed 3 months ago

Iframe added to the page by an extension no longer has storage access

Categories

(WebExtensions :: General, defect)

Firefox 140
defect

Tracking

(firefox-esr128 unaffected, firefox138 unaffected, firefox139 unaffected, firefox140 fixed)

RESOLVED FIXED
140 Branch
Tracking Status
firefox-esr128 --- unaffected
firefox138 --- unaffected
firefox139 --- unaffected
firefox140 --- fixed

People

(Reporter: colinmaxfield, Assigned: baku)

References

(Regression)

Details

(Keywords: regression, Whiteboard: [addons-jira])

Attachments

(2 files)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:139.0) Gecko/20100101 Firefox/139.0

Steps to reproduce:

At Pendo.io we provide an extension to our customers that allows them to use Pendo over the applications they want. As part of that extension, we are able to launch our Visual Design Studio over an application to design in-app guidance for these applications. Starting in Firefox 140, our extension is no longer able to launch the Visual Design Studio due to window.localStorage access throwing a "DOMException: The operation is insecure" in the pendo frames opened by our extension. Local storage is used to communicate between multiple of our own pendo frames added to the page and this access is necessary for it to function. The steps below will only work if you have access to a paid Pendo subscription but I will include them anyways.

  1. Install the Pendo Launcher add on (https://addons.mozilla.org/en-US/firefox/addon/pendo-launcher/)
  2. Log in to your Pendo subscription on app.pendo.io
  3. Launch the Visual Design Studio over the desired application.

This seems to be caused by the recent change in 140 Nightly to prevent access to referrer and storage by frames opened from extensions.
https://bugzilla.mozilla.org/show_bug.cgi?id=1962124
https://bugzilla.mozilla.org/show_bug.cgi?id=1957355

Actual results:

Errors are thrown in the console in our own app.pendo.io frame "DOMException: The operation is insecure."

Expected results:

As in Firefox 139, we should not be throwing errors for using local storage in our own frames.

Confirmed that it is due to the default change in the linked bugs. Setting "privacy.antitracking.isolateContentScriptResources: false" makes the frames work correctly again. I think we are going to need a way to programmatically get storage access as this will completely kill our product in Firefox and drive all of our customers towards Chrome.

What I'm not sure yet is if this is something that is solved by document.requestStorageAccess or not. If that is right path to take here feel free to let me know.

The Bugbug bot thinks this bug should belong to the 'WebExtensions::Untriaged' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Product: Firefox → WebExtensions
Flags: needinfo?(amarchesini)

Do you have any thoughts about this? In particular, do you think document.requestStoreAccess is the right move? And do you know if it's supported in the latest changes?

Flags: needinfo?(amarchesini) → needinfo?(tihuang)

By definition, document.requestStoreAccess allows an iframe to request access to client-side storage. So, it can be a path forward if we think the privacy implications of the injected content by extensions can be acceptable if the user agrees through the API.

However, the current implementation doesn't support the document.requestStoreAccess(). We will always reject the call in the current implementation.

Flags: needinfo?(tihuang)
Attached file iframe-dom-storage.zip

STR:

  1. Load attached extension at about:debugging in Nightly (or if testing non-Nightly (139+) - set privacy.antitracking.isolateContentScriptResources to true).
  2. Visit https://example.com
  3. Look at the frame that the extension adds (iframe src is same-origin).
  4. Visit https://example.net
  5. Look at the frame that the extension adds (iframe src is cross-site).

Expected:

  • At step 3, the iframe should be green - DOM storage access is allowed (same-origin).
  • At step 5, the iframe should be green - DOM storage access is allowed (cross-site).

Actual:

  • At step 3 and 5 the iframe is red - console shows Request to access cookie or storage on “https://example.com/?iframe” was blocked because we are blocking all storage access requests. and DOMException: The operation is insecure.

I thought that we were only going to strip referrer headers. Apparently bug 1957355 expands this to cookies, and due to the implementation even DOM storage. It is far from uncommon for extensions to insert an iframe in content scripts, so this restriction is unlikely to be compatible with extensions, to the point that we cannot ship this to release.

Can we not block storage access from frames inserted by extensions? As my STR in comment 6 shows, this restriction is even applied to same-origin frames.

Flags: needinfo?(amarchesini)
Keywords: regression
Regressed by: 1962124
See Also: → 1957355
Status: UNCONFIRMED → NEW
Component: Untriaged → General
Ever confirmed: true

Set release status flags based on info from the regressing bug 1962124

We have a meeting next week to discuss this issue in more detail. For now, let's disable this feature in nightly.

Flags: needinfo?(amarchesini)
Assignee: nobody → amarchesini
Status: NEW → ASSIGNED

Thank you so much for the update, let me know if you need anything else from me. Sorry for the doom and gloom in my previous messages, I panicked before I realized that I could at least turn it off using the config flag.

Whiteboard: [addons-jira]
Pushed by amarchesini@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/e8f59246d1ef disable the anti-tracking protection for injected resources via content script, r=robwu
Status: ASSIGNED → RESOLVED
Closed: 3 months ago
Resolution: --- → FIXED
Target Milestone: --- → 140 Branch

(In reply to Tim Huang[:timhuang] from comment #5)

However, the current implementation doesn't support the document.requestStoreAccess(). We will always reject the call in the current implementation.

That part is clearly a bug. We are still arguing over whether injected frames should be partitioned by default, but they definitely shouldn't be less capable than a frame inserted by the original page.

There will be strong pressure to provide an option for extensions themselves to create frames with storage access enabled: both to keep old extensions working and to avoid annoying users with storage access requests for content they presumably want their extension to be adding. The security team would prefer that require an explicit action on the part of extensions that could be checked in review (maybe a permission? an option/argument/attribute in the API?), but Web Extension team is concerned about breaking existing add-ons until their authors can update them (and all the addons with MIA authors who won't be around to update them).

For cases like Pendo.io I wonder if a better pattern would have been to sync the frames through the extension itself. If we ever got to the "no 3rd party cookies" world Chrome was pursuing with CHIPS, that, or storage access requests, would have been required anyway.

Local storage is used to communicate between multiple of our own pendo frames

storage is for state, not communication. Maybe the Broadcast Channel would be better suited? That's also partitioned and would be equally affected by this issue. I mention it as a general comment, not a "work around" for this (now fixed) regression. A "work around" would be for the frames to communicate via messages with the central extension.

avoid annoying users with storage access requests for content they presumably want their extension to be adding.

That presumption is often wrong, though: we discover and block a lot of shady extension, and are always finding more that slipped through. Permission prompts are annoying in the legitimate case, but their existence prevents bad extensions from trying things or aids in detecting them. The end result is that most users only see prompts in the cases that are "obviously OK" and therefore annoying.

(In reply to Daniel Veditz [:dveditz] from comment #14)

(In reply to Tim Huang[:timhuang] from comment #5)

However, the current implementation doesn't support the document.requestStoreAccess(). We will always reject the call in the current implementation.

That part is clearly a bug. We are still arguing over whether injected frames should be partitioned by default, but they definitely shouldn't be less capable than a frame inserted by the original page.

There will be strong pressure to provide an option for extensions themselves to create frames with storage access enabled: both to keep old extensions working and to avoid annoying users with storage access requests for content they presumably want their extension to be adding. The security team would prefer that require an explicit action on the part of extensions that could be checked in review (maybe a permission? an option/argument/attribute in the API?), but Web Extension team is concerned about breaking existing add-ons until their authors can update them (and all the addons with MIA authors who won't be around to update them).

For cases like Pendo.io I wonder if a better pattern would have been to sync the frames through the extension itself. If we ever got to the "no 3rd party cookies" world Chrome was pursuing with CHIPS, that, or storage access requests, would have been required anyway.

Local storage is used to communicate between multiple of our own pendo frames

storage is for state, not communication. Maybe the Broadcast Channel would be better suited? That's also partitioned and would be equally affected by this issue. I mention it as a general comment, not a "work around" for this (now fixed) regression. A "work around" would be for the frames to communicate via messages with the central extension.

There are definitely better options for us in the long run and with enough heads up (like Chrome has attempted to do but sometimes failed pretty badly) we can move towards the other options. The current state of things is mostly legacy though at this point, this is back from when Pendo had to support much older browsers with different limitations and so the code for the extension and standard Pendo are the same. We do actually requestStorageAccess to get access to unpartitioned storage but we currently get to that point in our code since we will also try to use partitioned localStorage before that point. Chrome (as far as I know) will always let us use the partitioned storage without storage requests but then we have to request (with user interaction which we do) access to unpartitioned. Our use of localstorage to communicate between frames is very much legacy at this point (at least 6 years old) and exists from time when we needed wider browser support.

Daniel do you know if this by chance got reverted back to the "broken" state? I am seeing the same failures that happened before but I am having a hard time finding the change listed in nightly.

We re-enabled the functionality, with an exception for document requests, which ought have prevented this regression, in bug 1973018. If you are experiencing this bug again, could you create a new report and add reproduction steps? Ideally with a minimal self-contained extension/test case.

In the future, if you are interested in identifying a (recent) regression, use mozregression: https://mozilla.github.io/mozregression/

See Also: → 1973018

(In reply to Rob Wu [:robwu] from comment #18)

We re-enabled the functionality, with an exception for document requests, which ought have prevented this regression, in bug 1973018. If you are experiencing this bug again, could you create a new report and add reproduction steps? Ideally with a minimal self-contained extension/test case.

Okay thank you, I will work on getting the simple repro case up because yeah we are back to the same state as the initial report it seems.

In the future, if you are interested in identifying a (recent) regression, use mozregression: https://mozilla.github.io/mozregression/

I have never used this before, thanks for the recommendation, I will add it to my tool bag.

(In reply to Rob Wu [:robwu] from comment #18)

We re-enabled the functionality, with an exception for document requests, which ought have prevented this regression, in bug 1973018. If you are experiencing this bug again, could you create a new report and add reproduction steps? Ideally with a minimal self-contained extension/test case.

Actually it looks like I can use your same steps from comment #6 to repro the issue, I will file it as a new bug

See Also: → 1973808
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: