Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iframe credentialless (was: Anonymous iframe) #628

Open
ArthurSonzogni opened this issue Apr 5, 2022 · 40 comments
Open

iframe credentialless (was: Anonymous iframe) #628

ArthurSonzogni opened this issue Apr 5, 2022 · 40 comments
Assignees

Comments

@ArthurSonzogni
Copy link

ArthurSonzogni commented Apr 5, 2022

Request for Mozilla Position on an Emerging Web Specification

Other information

WICG proposal. The Feedback section mentions who are the developers interested in anonymous-iframe.

+CC @mikewest @camillelamy

@annevk
Copy link
Contributor

annevk commented May 10, 2022

We have started looking at this, but need more time. Part of this proposal I think supports the argument in whatwg/storage#142 that we ought to refactor origin, storage key, and network partition key, into a new authority field (or equivalent) we take care of propagating correctly. That ultimately means that changes like this need to happen in fewer places and we can be more sure they end up impacting all the necessary places.

@ArthurSonzogni
Copy link
Author

Gentle ping ;-)
We would like experiment behind an origin trial in M106 (canary: Aug 18).
There are not a lot of days left and I would like to make sure AnonymousIframe's shape is something Mozilla's developers would be happy to ship.

Thanks for the 3 issues filled so far (#1, #2, #3). I did moving the anonymous bit into PolicyContainer. There are two filled issues left: the name and type of the attribute. I replied/explained and I am looking for your comments. Maybe @sefeng211 or @smaug---- have some opinions about this feature overall?

About @annevk last comment: Yes I think I agree with that.

@bgrins
Copy link
Member

bgrins commented Aug 1, 2022

Will defer to @smaug---- but my understanding is that the concern at WICG/anonymous-iframe#5 (comment) hasn't changed:

(In general I'm rather worried about adding yet another allow/disallow/tweak-features type of attribute to iframe and not reuse existing ones)

If it were possible to solve the usecase without introducing a new attribute that seems ideal. I do see the consideration against i.e. using a new sandbox flag at https://wicg.github.io/anonymous-iframe/#alternatives-sandbox - thanks for documenting that. This may be an uninformed question, but can you say more about why this wouldn't be achievable with something like sandbox="allow-same-origin disallow-credentials"?

@ArthurSonzogni
Copy link
Author

Thanks @bgrins!
Happy to switch to a different name if someone has some alternative proposition. I replied on the thread. We need to express something with the meaning of a "public iframe" / "~credentialless iframe" / "anonymous iframe".
I still have ~14 days before branch cut and starting experimenting. So the sooner, the better for me.

This may be an uninformed question, but can you say more about why this wouldn't be achievable with something like sandbox="allow-same-origin disallow-credentials"?

This doesn't fit sandbox attribute, because with sandbox, the iframe starts from the full "sandboxed" state and we can then allow again some of them with them with "allow-xxx". We can't express "disallow-xxx" with the syntax.
The goal of anonymous iframe was to load public document and minimizing breakage. With the sandbox syntax, users would get all the sandbox restrictions if they don't specify the full "allow-xxx" list. There are also some sandbox features that can't be toggled back.

@smaug----
Copy link
Collaborator

Yes you can express disallow-. Just use disallow-.

My worry with adding yet another attribute is that there isn't any coherent way to affect how iframes behave. We add more and more such attributes and the overall behavior becomes hard to define and understand.

@ArthurSonzogni
Copy link
Author

Yes you can express disallow-. Just use disallow-.

This would introduce the first "disallow-xxx" in the API.
How do you avoid the side effect of declaring iframe.sandbox? Ask developers to add all the allow-xxx flags? What about the features without a corresponding allow-xxx flag?

My worry with adding yet another attribute is that there isn't any coherent way to affect how iframes behave. We add more and more such attributes and the overall behavior becomes hard to define and understand.

Trying to avoid new attributes to spread is a nice goal. If we can, that's good. Sandbox doesn't look like a good one to me, but maybe there are some alternatives?

@camillelamy
Copy link

I would second Arthur's comment that using sandbox flags means that we would introduce the first disallow flag, and a whole new mechanism for how sandbox flags behave.

In this particular case, there is also an additional challenge in that this particular sandbox flag could not be settable through a CSP header. This is because the request for the iframe document must be done without credentials, but by the time we get a response with a CSP header asking for this flag, credentials have already been used to make the request.

Overall, it seems to us that the precise mechanism we need to implement is sufficiently different from sandbox flags that we should have a different attribute instead of having this as a part of sandbox flags.

@bgrins
Copy link
Member

bgrins commented Aug 2, 2022

In this particular case, there is also an additional challenge in that this particular sandbox flag could not be settable through a CSP header. This is because the request for the iframe document must be done without credentials, but by the time we get a response with a CSP header asking for this flag, credentials have already been used to make the request.

@camillelamy that's a good point and one I hadn't considered. If those headers are expected to reflect the sandbox attribute on frames then it would be surprising to add one that doesn't work the same. Might be worth capturing that in https://wicg.github.io/anonymous-iframe/#alternatives-sandbox.

@smaug----
Copy link
Collaborator

smaug---- commented Aug 2, 2022

Sandbox is already special when it comes to CSP. CSP with <meta> can't handle sandbox at all.

@ArthurSonzogni
Copy link
Author

Sandbox is already special when it comes to CSP. CSP with can't handle sandbox at all.

Yes, I agree the interaction with CSP and response headers is not a hard blocker for using sandbox, we could just ignore them, because it is too late.
What is blocking IMO is still that sandbox is different from anonymous iframe and iframe.sandbox can only express a set of allow-xxx. You can't define a disallow-xxx with the current sandbox syntax/behavior. By setting iframe.sandbox="allow-same-origin disallow-credentials", you would get all the unwanted sandbox restrictions and potentially a broken iframe. Sandbox flags syntax would have worked best if anonymous iframe was the default and you could allow credentials with allow-credentials. WDYT @smaug---- of my previous questions? #628 (comment)

@smaug----
Copy link
Collaborator

You can define disallow-xxx with sandbox. You just do it. One would need to define something new, but adding a totally new attribute is a new thing too.
But I'm not stuck with sandbox itself, just trying to figure out some way to not add yet another sandbox/allow/allowfullscreen/etc

Though, I wouldn't be surprised if credentialless iframes will be usually also sandboxed. One probably doesn't want to let ads and such to do top level navigations for example.

Do you have some concrete examples which would be broken with sandbox + disallow ? Such examples may reveal issues in the sandbox itself, like missing allow-*.

@ArthurSonzogni
Copy link
Author

@mikewest also noted sandbox flags are inherited toward popups. This conflicts with the design where we decided the anonymous attribute do not propagate to popups (here)

We would have to define some exceptions to the current logic if we go this way.


Though, I wouldn't be surprised if credentialless iframes will be usually also sandboxed. One probably doesn't want to let ads and such to do top level navigations for example.

Yes, that's very likely true.


Do you have some concrete examples which would be broken with sandbox + disallow ? Such examples may reveal issues in the sandbox itself, like missing allow-*.

I was mostly annoyed that the closest equivalent to:

<iframe anonymous>

becomes:

<iframe sandbox="disallow-credentials allow-downloads allow-forms allow-modals
allow-orientation-lock allow-pointer-lock allow-popups
allow-popups-to-escape-sandbox allow-presentation allow-same-origin
allow-scripts allow-top-navigation">

Yes, users may already be using sandbox, in this case, this is not really annoying for them.

About the flags we can't allow-xxx back. I see:

I also initially suspected kAutomaticFeature, but it is essentially an alias for kScript.

I will check what others are thinking about using sandbox.


But I'm not stuck with sandbox itself, just trying to figure out some way to not add yet another sandbox/allow/allowfullscreen/etc

Among all the existing attributes. It remains allow, I don't know enough yet to have an opinion.

<iframe allow="credentials='none'">

Not sure how it works with regards to inheritance and how to deal with the possible <allowlist>

@ArthurSonzogni
Copy link
Author

Hello @smaug----
I discussed, mostly with @mikewest and @antosart

Developer experience is the annoying thing about the disallow- framing. Needing to specify every allow- flag to get mostly back to normal behavior isn't nice. But maybe we can define it as:

<iframe sandbox="allow-all disallow-credentials">

to switch the sandboxing parser into something of a blocklist as opposed to an allowlist?


About

window.anonymouslyFramed

it has to be renamed. Maybe:

window.credentialless

?


It is promising if the objection is only about how things are named/activated and not about how things work. @smaug---- what do you think would be Mozilla position if this is moved to a sandbox flag?

I didn't get any feedback from Webkit yet:
https://lists.webkit.org/pipermail/webkit-dev/2022-April/032205.html
Since they are now using Github too, I will ask again on this medium and let them know about @smaug---- sandbox flags proposition. This might get some attention this time.

@ArthurSonzogni
Copy link
Author

@bgrins or @smaug---- Do you have any other feedback about the feature outside of how it is activated/spelled (sandbox vs anonymous)? Is it good in your opinion?

@smaug----
Copy link
Collaborator

In general I do like the concept of credentialless/anonymous iframes.

allow-all doesn't feel too future proof. I'm not yet convinced it is needed. At least it isn't anything which must be added initially.

Also, the popup opening handling (noopener by default) is kind of separate primitive to credentialless loads.
Perhaps it could be separated out, but maybe that can happen later, if credentialless iframe need it always.
(Now I started to wonder why opened windows aren't also credentialless. I think I can see use cases for both new windows with noopener and credentials and new windows with opener but without credentials. Perhaps something to add later to support the latter case.)

@ArthurSonzogni
Copy link
Author

ArthurSonzogni commented Aug 11, 2022

In general I do like the concept of credentialless/anonymous iframes.

Great! I am pleased about this!


allow-all doesn't feel too future proof. I'm not yet convinced it is needed. At least it isn't anything which must be added initially.

I agree.


Also, the popup opening handling (noopener by default) is kind of separate primitive to credentialless loads.
Perhaps it could be separated out, but maybe that can happen later, if credentialless iframe need it always.
(Now I started to wonder why opened windows aren't also credentialless. I think I can see use cases for both new windows with noopener and credentials and new windows with opener but without credentials. Perhaps something to add later to support the latter case.)

Popup aren't allowed, because they can be used in OAuth flow to retrieve credentials. In a crossOriginIsolated environment, the attacker can use Spectre to exfiltrate personalized data. See this section of the threat model. COOP:same-origin already require breaking the openee/opener relationship so this isn't an immediate problem, but this will with COOP:restrict-properties.

Iframes are different in kind from popup: Users can't verify the URL of the iframe's document. We aren't worried of the user typing their credentials directly inside, because from the user's perspective, there are no difference with a malicious website mimicking the iframe with its own HTML elements and a legitimate iframe.

I am prototyping the sandbox alternative. The conceptual difficulty I am seeing is that sandbox flags may be inherited to popup. It means we have to support some kind of "anonymous main frame". This is new. Not sure how to properly handle this.

@ArthurSonzogni
Copy link
Author

If one of you @smaug----, @bgrins or @sefeng211 are going to TPAC 2022 in 2 weeks, this could be the perfect opportunity to discuss this.

@smaug----
Copy link
Collaborator

I'll be there :)

@RByers
Copy link

RByers commented Nov 1, 2022

Any progress from discussion at TPAC? There's now an I2S on blink-dev for this. I've weighed in with my initial support personally, but I'm willing to be convinced that there are some concrete steps that should be taken first.

@bgrins
Copy link
Member

bgrins commented Nov 1, 2022

FYI smaug is away this week, but when he's back I'd like his feedback coming out of discussion at TPAC & issues like WICG/anonymous-iframe#5

@bgrins
Copy link
Member

bgrins commented Nov 3, 2022

We're negative on this one until open API issues are resolved. We may or may not support after that depending on the outcome - would like to hear more about the discussion at TPAC and have a chance to discuss with smaug.

@smaug----
Copy link
Collaborator

Folks from Google said at TPAC that they will ask the origin trial users whether sandbox is always used with anonymous iframes and report back (since that information might affect the API design). I haven't heard anything back and I was rather surprised to see intent-to-ship.

Also, this isn't really anonymous, but credentialless,

@ArthurSonzogni
Copy link
Author

ArthurSonzogni commented Nov 4, 2022

Hi @smaug---- !

Following our discussion at TPAC, We're still concerned that the model with several sandbox flags to use in conjunction, including the first disallow flags is hard to explain to developers. There are several open questions we don't know how they can be solved.

Considering this, we think the current solution is the better one. We have feedback from partners that it solves their need, and are under tight timeline to provide them with a way to keep using SABs on their website by allowing them to deploy cross-origin isolation. Considering that we have no clear feedback so far that Mozilla would be interested in implementing anonymous iframes even if they were spelled as sandbox flags, we made the decision to ship with what we have implemented.

We should have updated the email thread, but due to travelling/COVID, this fell through. I am sorry about this. Here are the results.

@ArthurSonzogni
Copy link
Author

ArthurSonzogni commented Nov 8, 2022

We decided to address issue #5: “rename anonymous iframe into iframe credentialless”. We acknowledge this is not the core disagreement. It is about controlling the feature via multiple new sandbox flags. We think it is much less ergonomic and makes the feature harder to explain to developers. The integration with sandbox flags has some challenging problems listed in this document. We don’t know ways to overcome some of them. So we would like to continue without sandbox flags.

@ArthurSonzogni
Copy link
Author

We discussed Iframe credentialless yesterday, during the WebAppSec working group, with @dveditz 👋
See the minutes: https://github.com/w3c/webappsec/blob/main/meetings/2022/2022-11-16-minutes.md
In particular, see Dan comments-1 and comment-2. We agree that shipping this particular bundle of features in a way that makes it simpler for developers to opt into cross-origin isolation is an important short-term goal, and that it would be good in the long term to provide a mechanism by which developers could access individual features within that bundle. We'll continue working together on that latter goal, and shipping the bundle doesn't preclude that work in any way. From there, what are the next steps to resolve this standard position?

@ArthurSonzogni
Copy link
Author

From there, what are the next steps to resolve this standard position?

? 🥺

@FezVrasta
Copy link

FezVrasta commented Feb 7, 2023

I'm no expert, but I see some overlap between allow-same-origin and credentialless, is there any reason why credentialless can't become a less restrictive allow- version of the former?

Considering the cookie access, there could be a new allow-scoped-origin that would only provide cookies from the anonymous context rather than the parent window one.

This would be backwards compatible because anyone using allow-same-origin would keep experiencing the same less restrictive behavior, but new users using only allow-scoped-origin would opt-in into this stricter one.

<!-- New flag -->
<iframe sandbox="allow-scoped-origin"></iframe>
<!-- Old flag, which effectively overrides the strictness of the new one -->
<iframe sandbox="allow-scoped-origin allow-same-origin"></iframe>

Am I missing something? Is there any rule that forbids two allow- rules to be a subset of the other?

@Sora2455
Copy link

Sora2455 commented Feb 8, 2023

@FezVrasta The trouble is that you are trying to add a sandbox directive that removes functionality, while every other sandbox directive adds it back in. The most restrictive sandbox directive is sandbox="". Your change would only make sense if all sandboxes were changed to have scoped cookies by default, and then had unscoped cookies if given a specific directive - which is not backwards compatible.

@FezVrasta
Copy link

FezVrasta commented Feb 8, 2023

@FezVrasta The trouble is that you are trying to add a sandbox directive that removes functionality, while every other sandbox directive adds it back in. The most restrictive sandbox directive is sandbox="". Your change would only make sense if all sandboxes were changed to have scoped cookies by default, and then had unscoped cookies if given a specific directive - which is not backwards compatible.

No I'm not removing functionalities. A full sandbox doesn't allow cookies access, you need the allow-same-origin to access them.

You would have 3 tiers:

  • sandbox="" > no cookies access
  • sandbox="allow-scoped-origin" > scoped cookies access
  • sandbox="allow-same-origin" > parent window cookies access

@ArthurSonzogni
Copy link
Author

ArthurSonzogni commented Feb 8, 2023

Thanks @FezVrasta! Here is a paragraph about this.

The navigation response in a credentialless iframe is requested without credentials 1. This is key to the security story. That's not the case for fully sandboxed iframe.
So, in some sense "allow-scoped-origin" and "not-allow-same-origin" are both stricter to each other, depending on where you look at.

Secondly, "allow-scoped-origin" would need not to be inherited to popup like a normal sandbox flag. Otherwise users would be stuck in a never ending credentialless tab. The opened website would not be able to behave correctly if the cookie/network/storage context is renewed everytime the user navigate within it. The iframes blocking COEP deployment are often ads, and this would likely prevent developers from using credentialless iframe. Iframes would continue to block COEP deployment. More generally, users wouldn't understand why every website displayed in this tab are unable to maintain a state.

Footnotes

  1. To be more specific, I should say: "requested with a cookie partition scoped to the current top-level document"._

@coatless
Copy link

Greetings and Salutations all 👋,

I'm coming from the R world that recently gained the ability to have R in the browser through webR, which uses WebAssembly via Emscripten. Unfortunately, we need to set both COOP and COEP headers to speed up the page load (to avoid students navigating away). But, we then lose the ability to embed lecture videos since COEP is interfering with iframe video embedding.

Would it be possible to further standardize the credentialless iframe behavior across web browsers? As it stands now, we have to request students to use a chromium-based browser for the credentialless attribute.

@smaug----
Copy link
Collaborator

One thing I'm not very keen on in credentialless iframes is that they don't get their own origin (I mean own vs non-credentialless iframes), only storage partitioning. So if one uses non-credentialless iframes and credentialless iframes in a same page, one gets the weird behavior where they may touch each others, but how data is stored depends on which iframe is used for it. And that would mean some page in a site is using COEP for a reason and gets credentials, but other page wasn't meant be used that way, yet they
now live inside the same top level page and can touch each others.
That feels error prone.
Would be better to key the origin itself, not only the storage key.

Also, it is unclear how StorageManager works with this. Is there a risk that StorageManager.estimate() can be used as a side channel to communicate with the credentialless iframe? Or if not, does that mean one can get double the storage space (half of it temporary) by just using <iframe credentialless> (no uri, so it gets same origin about:blank)?

@ArthurSonzogni
Copy link
Author

ArthurSonzogni commented Apr 4, 2023

One thing I'm not very keen on in credentialless iframes is that they don't get their own origin.

It would look like an idea derived from: webappsec-suborigins.

Instead of reusing storage-partitioning, we would have instead of implement everything separately for origin-partitioning. We would have to go through every web APIs keyed by an origin.

Not depending on storage-partitioning is orders of magnitude more difficult. Do you think modifying the origin would make it more likely to be implemented by Firefox? Or less likely?

@ArthurSonzogni
Copy link
Author

Also, it is unclear how StorageManager works with this. Is there a risk that StorageManager.estimate() can be used as a side channel to communicate with the credentialless iframe? Or if not, does that mean one can get double the storage space (half of it temporary) by just using <iframe credentialless> (no uri, so it gets same origin about:blank)?

=> Double storage space (half of it temporary). See new WPT.

Iframe credentialless augments the storage key. Then, everything is the consequence of how storage partitionning is defined. See quota-storage-partitioning:

Quota: The quota system must manage each partition as a separate bucket for
determining how much space is permitted and when it should be cleared. This also
includes APIs that give information on quota to the website, such as
navigator.storage.estimate(). 

To avoid using quota as a communication channel, it sounds like a reasonable thing.

It also implies one can get additional storage space using partitioning in general, especially when using the cross-origin ancestor bit in storage key. Objections to that scheme would entail changes to partitioning generally, not credentialless iframes specifically.

@smaug----
Copy link
Collaborator

Why would origin-partitioning be any harder? And I guess that isn't even the right question. The question is what is the most reasonable API for the Web?
But I think in Gecko origin-partitioning should be even simpler. In some sense it is a bit like container tabs, the origin just has an extra origin attribute attached to it, and the storage would just use the same thing (same principal in Gecko terminology)

And storage usage, does Chrome really allow a site to fill the whole disk if it uses <iframe credentialless> ?
Assuming recently updated https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria is still up-to-date, a site could use 120% of disk space, with credentialless.

@smaug----
Copy link
Collaborator

Objections to that scheme would entail changes to partitioning generally, not credentialless iframes specifically.

Well, credentialless iframes should just not use partitioned storage, they should have their own origin-partitioning.

@adamziel
Copy link

adamziel commented Apr 25, 2024

Lack of credentialless support is an issue for Firefox users browsing specific WordPress sites. You can't do these two at the same time:

  • Use iframes to embed content from other sites
  • Use SharedArrayBuffer

These two require conflicting CORP headers, but can work together with <iframe credentialless>. See swissspidy/media-experiments#294 for more details.

@Siderite
Copy link

Any news on this? At least some estimation on if and when this might be available?

@annevk
Copy link
Contributor

annevk commented Sep 28, 2024

I wanted to point out here that this feature might result in security issues due to websites using it for authenticated scenarios for which the feature does not really work. See WebKit/standards-positions#45 (comment) onward. I personally think we need to go back to the drawing board.

@Siderite
Copy link

I am not a security guy and I don't know much about how YouTube or Vimeo work, but it shouldn't be impossible to be able to show a running video in an isolated iframe popup, which is my current scenario. And I am sure you know it works in Chrome since forever. Are you saying all Chromium browsers are hackable because of it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Needs proposed position
Development

No branches or pull requests