whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
7.96k stars 2.6k forks source link

srcdoc and sandbox interaction with session history #6809

Open jakearchibald opened 3 years ago

jakearchibald commented 3 years ago

First up is a simple one: Does setting srcdoc replace the current history entry or add a new one?

Chrome & Firefox: Replace if the current document url is about:srcdoc, otherwise add. Safari: Always replace.

I'm pretty sure Chrome & Firefox are doing the right thing here and it's somewhat spec'd.


How is a srcdoc entry stored in session history? It's currently unspec'd.

Test:

  1. https://iframe-session-history.glitch.me/.
  2. Set cookie: give all responses no-store (just to stop bfcache).
  3. iframe-1: Set srcdoc to Math.random().
  4. iframe-1: Navigate to 'one' via location object.
  5. iframe-1: Set srcdoc to Math.random().

This creates history entries [srcdoc1, 'one', srcdoc2] in Chrome/Firefox and [srcdoc1, srcdoc2] in Safari.

Each browser behaves differently when traversing to the srcdoc entries.

Chrome: Recreates the document using the srcdoc of the iframe. As in srcdoc1 and srcdoc2 use the same source, which is different to the source srcdoc1 used when it was first created.

Firefox: Seems to store the srcdoc source along with the history entry, so srcdoc1 and srcdoc2 use different source, which is each the source they were created with.

Safari: Restores the original history entries in these places, as if the srcdoc stuff never happened.

Another test:

  1. https://iframe-session-history.glitch.me/.
  2. Set cookie: give all responses no-store (just to stop bfcache).
  3. iframe-1: Set srcdoc to Math.random().
  4. "Navigate to same origin page"
  5. back()

Chrome: iframe empty. I guess this is because it looks at the srcdoc of the iframe which is empty, since the page has reloaded.

Firefox: Restores the iframe to its previous content.

Safari: Restores the iframe as if setting srcdoc never happened.

This seems consistent with the findings above. Firefox's model seems to make the most sense to me. Chrome's behaviour is ok I guess. Safari's behaviour is plain weird.

jakearchibald commented 3 years ago

Something I haven't looked at yet: When going back(), do the srcdoc iframes take their CSP rules from the parent as it is now, or as it was when the srcdoc page was created?

domenic commented 3 years ago

/cc @domfarolino @antosart for the CSP rules question. I am pretty sure that has a canonical answer as to how it should be, given recent policy container work.

antosart commented 3 years ago

I believe the answer for CSP rules depends on the answer to the main question (whether the srcdoc content is reloaded when navigating back or not).

If we store the content of srcdoc in history, we should also store the policies. If we reload the srcdoc attribute (which might have changed) on history navigations, then I guess we should also re-inherit the policies from the parent.

I believe the currently specced behaviour is to store the policies in history for srcdoc. This is also implemented in chrome.

(This is not tested for CSP at the moment I believe, although it is for referrer-policy, see the file referrer-policy/generic/inheritance/iframe-inheritance-history-about-srcdoc.html)

jakearchibald commented 3 years ago

If we store the content of srcdoc in history, we should also store the policies. If we reload the srcdoc attribute (which might have changed) on history navigations, then I guess we should also re-inherit the policies from the parent.

Agreed.

I believe the currently specced behaviour is to store the policies in history for srcdoc.

The spec doesn't seem to cover restoring srcdoc pages at all, unless I'm missing something.

This is also implemented in chrome.

I don't think so. See the tests above – it seems like Chrome goes back to the srcdoc defined in the page.

I tested Firefox, and it does seem to store the CSP rules along with the srcdoc src, so it's like it stores the whole response. That's what I'll spec for now, and we can look at it again later if needed.

antosart commented 3 years ago

I believe the currently specced behaviour is to store the policies in history for srcdoc.

The spec doesn't seem to cover restoring srcdoc pages at all, unless I'm missing something.

Sorry, I just meant w.r.t. policy inheritance (which might never be called because the spec does not cover navigating back to srcdoc). And I actually was mistaken: we explicitly excluded srcdoc when storing policies in history

This is also implemented in chrome.

I don't think so. See the tests above – it seems like Chrome goes back to the srcdoc defined in the page.

Also here I was referring to policies. Chrome reloads the srcdoc content from the srcdoc attribute, but stores and reloads the policies from history.

Back to the original question: if we store the content of the srcdoc attribute in history, then we should probably store other attributes as well (I am thinking at sandbox for example, or allow). I am not totally sure I am convinced that that is better than reloading everything on history navigations.

jakearchibald commented 3 years ago

I think it comes down to what you'd expect to happen here:

  1. Navigate iframe to '/a'.
  2. Set iframe sandbox attribute and navigate iframe to '/b'.
  3. Press back.

Should '/a' be sandboxed?

antosart commented 3 years ago

Another good question! I am not sure.

For history navigations to srcdoc it seemed to be slightly more clear to me, in order to avoid the asymmetry of getting one attribute (srcdoc) back from history while re-parsing another one (sandbox) from the