mozilla / standards-positions

https://mozilla.github.io/standards-positions/
Mozilla Public License 2.0
611 stars 69 forks source link

Anonymous iframe #628

Open ArthurSonzogni opened 2 years ago

ArthurSonzogni commented 2 years ago

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 commented 2 years ago

We have started looking at this, but need more time. Part of this proposal I think supports the argument in https://github.com/whatwg/storage/issues/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 commented 2 years ago

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 commented 1 year ago

Will defer to @smaug---- but my understanding is that the concern at https://github.com/WICG/anonymous-iframe/issues/5#issuecomment-1184287166 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 commented 1 year ago

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---- commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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---- commented 1 year ago

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

ArthurSonzogni commented 1 year ago

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? https://github.com/mozilla/standards-positions/issues/628#issuecomment-1202335290

smaug---- commented 1 year ago

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 commented 1 year ago

@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 commented 1 year ago

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 commented 1 year ago

@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---- commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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---- commented 1 year ago

I'll be there :)

RByers commented 1 year ago

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 commented 1 year ago

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

bgrins commented 1 year ago

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---- commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

? 🥺

FezVrasta commented 1 year ago

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 commented 1 year ago

@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 commented 1 year ago

@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:

ArthurSonzogni commented 1 year ago

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.

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

coatless commented 1 year ago

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---- commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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