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

Allow auto-resize on iframe #555

Open
craigfrancis opened this issue Jan 25, 2016 · 26 comments
Open

Allow auto-resize on iframe #555

craigfrancis opened this issue Jan 25, 2016 · 26 comments
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest

Comments

@craigfrancis
Copy link

Considering the removal of <iframe seamless> on issue #331.

For me, the main feature of @seamless was the ability for the iframe to resize based on the size of the child document (really just the height), so no scroll bars would appear.

Currently this is "solved" with the use of some very messy JavaScript:

http://stackoverflow.com/search?q=resize+iframe

Which is more difficult cross-origin, which needs postMessage and custom JS running on every single page (both child and parent).

The suggestion of Shadow-DOM is interesting, but I don't believe this provides the same level of protection (and backwards compatibility), as often the child content is put in an iframe to keep it isolated from the current page (i.e. for security reasons).

Typically I put things in an iframe because they could easily be malicious, and I would really like to use a sandbox to block allow-scripts.

@zcorpan zcorpan added the addition/proposal New features or enhancements label Jan 25, 2016
@zcorpan
Copy link
Member

zcorpan commented Jan 25, 2016

For cross-origin I suppose the embeddee would need to opt-in somehow (e.g. meta tag), to not expose new information cross-origin.

@annevk
Copy link
Member

annevk commented Jan 25, 2016

@craigfrancis you might want to raise this on https://lists.w3.org/Archives/Public/www-style/. In theory this mostly seems like a problem with styling although if this needs to work cross-origin the problem is indeed a little bigger.

@zcorpan
Copy link
Member

zcorpan commented Jan 30, 2016

Some discussion in www-style
https://lists.w3.org/Archives/Public/www-style/2016Jan/thread.html#msg236

@annevk @mikewest do you have an opinion about using CORS to allow this for cross-origin? Or would it be better to use CSP or something else?

@annevk
Copy link
Member

annevk commented Jan 30, 2016

CORS does not seem great since you only share the height, nothing else. CSP is about adding restrictions. I guess it would be something else. But perhaps we should first see if it gets implemented for the same-origin scenario.

@craigfrancis
Copy link
Author

The iframe auto-resize (height) is more of a problem when it's cross origin, as on same origin you can hack this behaviour with:

document.getElementById('iframe').contentWindow.document.body.scrollHeight;

It does fail when the iframes content changes (e.g. navigating to a new page), but there are ways around this:

https://github.com/davidjbradshaw/iframe-resizer/blob/master/src/iframeResizer.js
https://github.com/house9/jquery-iframe-auto-height/blob/master/src/jquery-iframe-auto-height.js
https://raw.githubusercontent.com/cowboy/jquery-resize/v1.1/jquery.ba-resize.js

Ideally we just want to replace all of this browser specific / buggy JavaScript with one line of CSS, the current suggestion being:

iframe { height: max-content; }

This will become even more powerful when cross origin... but as noted, CORS gives too many permissions, CSP is really to restrict access with frame-ancestors, and X-Frame-Options is going away.

So while I'll try to push for this to be implemented, do you have any ideas for handling this securely?

@annevk
Copy link
Member

annevk commented Jan 31, 2016

A new header of sorts seems like the way to go. Expose-Height-Cross-Origin: 1 or something lame like that. You could ask https://lists.w3.org/Archives/Public/public-webappsec/ for additional input though I doubt they'd say anything different.

@craigfrancis
Copy link
Author

@mikewest
Copy link
Member

mikewest commented Feb 1, 2016

I agree with @annevk; you need something to mitigate the kinds of leakage that this feature would expose. <iframe seamless> was limited to same-origin for this reason. I'm sure we could get away with something less limiting for this subset of seamless's functionality, and I agree that it would be useful.

Expose-Height-Cross-Origin, however you end up spelling it, is probably a reasonable approach. CORS would certainly work, but probably gives away more than you'd like, and CSP isn't the right place for it, as I'd like to keep it negative to the extent possible.

@domenic
Copy link
Member

domenic commented Feb 1, 2016

Given that CORS is almost always safe, are we really concerned about "giving too much away"? The only case where a more restrictive header would be useful is if an intranet site wanted to expose its contents' height variation to height-variable iframes, but did not want to expose itself to the wider internet (except through a cross-origin iframe viewport). Is that enough of a use case to justify a new header?

@annevk
Copy link
Member

annevk commented Feb 1, 2016

Well, <iframe> is loaded with credentials at which point CORS might not be safe. You might be okay sharing your height, but not your credentialed content. The fetch mode is also "navigate" which thus far has no interaction with CORS and I don't think we want to start introducing that just for exposing the height.

@mikewest
Copy link
Member

mikewest commented Feb 1, 2016

@domenic: Consider a service like Disqus, which would love to use something like this (and were big advocates for @seamless. They would not be interested in making themselves CORS-same-origin with every site on the net, as that would (for instance) give the sites knowledge of the user's logged-in state.

@domenic
Copy link
Member

domenic commented Feb 1, 2016

Got it, credentials are the problem. Too bad there's no way to use CORS headers to automatically prevent credentials from being sent for cross-origin requests.

@craigfrancis
Copy link
Author

Just to keep everything together, I've written my notes up at:

https://github.com/craigfrancis/iframe-height

This includes links to the different browsers feature requests.

And a second thought did occur to me... we could look at a new CSS keyword for the resize property, which would be useful to automatically increase its height based on its content - another problem which requires JavaScript to solve.

@zcorpan
Copy link
Member

zcorpan commented Feb 8, 2016

Thank you, excellent work!

The resize property seems like a bad fit for this I think. It's about letting the end user resize an element, but this is not. In principle it could be defined that height: max-content "works" for textarea as well, but that should probably be a separate discussion (new thread on www-style).

@craigfrancis
Copy link
Author

Fair point... last week I happened to be replacing some JavaScript that automatically resized a textarea (the JS turned out to be buggy), and I came across a discussion about the 'resize' property for end users (something I don't block, because I think users should be able to change this), and I was wondering if they are kind of exclusive... as in, if the textarea auto resizes, then the user won't need to resize it themselves.

@brunoais
Copy link

@zcorpan Any updates on this subject?

@annevk annevk added the needs implementer interest Moving the issue forward requires implementers to express interest label Feb 19, 2018
@sashafirsov
Copy link

sashafirsov commented Feb 20, 2018

@annevk , this question and quite a bit above is in focus of https://github.com/EPA-WG/embed-page
POC could be seen at https://www.webcomponents.org/element/EPA-WG/embed-page/demo/demo/index.html

@Malvoz
Copy link
Contributor

Malvoz commented Jul 29, 2018

For cross-origin I suppose the embeddee would need to opt-in somehow (e.g. meta tag), to not expose new information cross-origin.

Now that we have Feature Policy, I think that's the way to go about that. Similarly, there is a proposal to expose bounds cross-origin.

@briansmith
Copy link

Now that we have Feature Policy, I think that's the way to go about that. Similarly, there is a proposal to expose bounds cross-origin.

Content Security Policy (CSP) already has a mechanism, e.g. Content-Security-Policy: frame-ancestors 'self' to control which origins are allowed to frame a document at all. In w3c/webappsec-csp#391 I proposed to extend CSP with a directive to control whether or not the framing document may see just enough information about the iframe's contents to be able to resized it based on its contents. I think it makes more sense to extend CSP than to use feature policy for this, because the CSP frame-ancestors policy already controls a subset of what is needed for this feature (see the issue I filed there).

Note that this issue is marked "needs implementer interest." I encourage people building websites and people building third-party widgets to express their interest in this feature, as it would be a significant security improvement that would help eliminate much use of <script src> for third-party content.

@annevk
Copy link
Member

annevk commented May 9, 2019

FWIW, w3c/csswg-drafts#1771 is probably the most significant other issue here and there should be some progress there too on a more formal definition of "contents" as I noted in a comment.

@annevk
Copy link
Member

annevk commented May 9, 2019

How big of a problem is it that navigation of the <iframe> ends up resizing it? It does not seem like a security issue as we already expose navigation in other ways, but it doesn't seem like a great experience either. There might also be some complications here in multi-process architectures if know the embeddee gets to influence the final size.

@craigfrancis
Copy link
Author

Starting with consent, we have it both ways - The parent page will opt-in to re-sizing it's iframe via CSS height: max-content; and the child opts-in though a header (where I like @briansmith's suggestion of a CSP frame-ancestors-resizing directive, but also happy with Expose-Height-Cross-Origin: 1).

And for a "first version", I'd still be happy if scrollbars appeared on navigation - as most use cases I can think of don't use navigation.

That said, content can change, and while the browser would ideally change the height automatically, I recognise that it can get into some circular issues.

So how about, the child page calls a method, such as window.parent.resizeMePlease() (when it has finished updating its content), and this asks the browser to do a re-size.

It's not perfect, but the current iframe implementations currently require the child to do a window.parent.postMessage() to tell the parent what size it should be (have fun calculating that), and for the parent to have some JavaScript listening for that message, and applying the new height.

In the case of third party widgets, this means it's much easier to give websites an un-safe <script src="..."> to include (full access to the pages content, and more), rather than a more secure (locked-down) and simple <iframe src="..." style="height: max-content">.

@briansmith
Copy link

briansmith commented May 9, 2019

How big of a problem is it that navigation of the <iframe> ends up resizing it? It does not seem like a security issue as we already expose navigation in other ways, but it doesn't seem like a great experience either.

The kind of use case I'm envisioning would require the use of several controls in concert. On the embedding side, at least:

<iframe
    src="https://my.domain.org.comments.example.com/my-url-slug"
    sandbox="allow-scripts allow-top-navigation-by-user-activation"
    csp="navigate-to 'none'; object-src 'none'">
</iframe>

In particular, I expect the embedder would/should normally disable navigation within the frame using CSP-EE.

On the embedded widget side, they'd need to opt into CSP-EE and also this iframe resizing thing.

[Edited to change the CSP-EE and iframe sandbox directives].

@felixfbecker
Copy link

I am a bit confused why the security concern is a blocker for <iframe>, when <object> already does this (at least when embedding an SVG, even cross-origin). <iframe>s are a lot more secure because they have attributes like sandbox and csp, which <object> does not. So currently we are forced to use <object> to embed SVGs in a responsive, accessible, interactive way (<img> doesn't expose contents to screen readers, make links clickable nor text selectable) with no way to disallow scripts in SVG to run. Having iframe resizing would therefor be an improvement to security in my eyes because it stops forcing us to use less secure alternatives.

@annevk
Copy link
Member

annevk commented Dec 9, 2020

I thought this proposal was for more than SVG? And it's not clear we'll keep the behavior for <object> the same. There are a number of inconsistencies across browsers there too.

@brunoais
Copy link

Almost 2 more years again. Any updates?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest
Development

No branches or pull requests

10 participants