Closed ojanvafai closed 2 years ago
Any consideration of doing this for modal dialogs as well? When I saw the email about not opening "popups" except in response to a user gesture, was excited about this because I thought it included blocking that particular behavior as well. A lot of abusive pages use OnBeforeUnload dialogs, which are just annoying.
blink-dev thread: https://groups.google.com/a/chromium.org/d/msg/blink-dev/Xi8-y4ySjA4/dc4BFfqyBQAJ
/cc @annevk @rlbmoz @johnwilander @travisleithead
:( This breaks a thing I'm working on. I'm trying to expose a cross-origin API in an iframe via postMessage. The parent frame uses postMessage to request a service from the iframe. If the request can be fulfilled without user confirmation, the iframe navigates the parent to a "success" page specified by the caller. Otherwise it makes a POST that navigates the parent frame to a confirmation page, which takes the user back to the specified "success" page after the user gesture.
I like the iframe top navigation pattern for a couple of reasons.
Compare it to the traditional workflow for doing this (as with OAuth) which requires POSTing directly to the cross-origin resource or opening a popup:
The parent could implement another listener for a postMessage reply and do the navigation itself, but that makes using this kind of API more complicated, and it is nice to be able to do the POST from the iframe and include, e.g. a CSRF token and trustworthy indication of the parent origin that triggered the request.
A click to the iframe doesn't make sense; it takes away control over the UX that the parent wants.
Since a page that doesn't want this behavior from an iframe already has the ability to block top-navigation with the sandbox attribute, I'm not sure why we need to break this behavior by default?
Could we count receiving a postMessage from the parent as enabling navigation? (in addition to a user gesture)
For payments security, we collect sensitive card information within an embedded iFrame. A lot of our clients depend on our iFrame for this. Once the card information is collected in the iFrame, the user is then navigated (by changing window.top) to a page in our domain for authentication of the card information. This proposed change will break our flow permanently.
If allow-top-navigation is mentioned in the
This is breaking sign-in flow for CapitalOne (https://servicing.capitalone.com/c1/Login.aspx). I see the following message in console:
Unsafe JavaScript attempt to initiate navigation for frame with URL 'https://servicing.capitalone.com/c1/Login.aspx' from frame with URL 'https://login2.capitalone.com/loginweb/login/postLogin.do'. The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor is it processing a user gesture. See https://www.chromestatus.com/features/5851021045661696.
I presume Capital One will have to fix their site, and Chrome is working as intended?
We received user reports that this is breaking users of the Facebook SDK. https://developers.facebook.com/docs/games/gamesonfacebook/login explicitly encourages use of top level navigation.
@reginaldos thanks for the report. Can you point us to an example page? We considering changing behavior here and being able to verify the new idea works would be helpful. It's hard for me to follow in that SDK documentation where top-level navigation is used.
@ojanvafai this also seems to break typeform redirection
This broke eBay checkout flow for me. It hung after adding a credit card in PayPal, and an error in the console pointed me to this new Chrome feature.
In the console:
main.js:21966 Unsafe JavaScript attempt to initiate navigation for frame with URL 'https://mbuy.ebay.com/xo?action=view&sessionid=(redacted)&redirect=mobile' from frame with URL 'https://www.paypal.com/webapps/helios?action=addCard&payer_id=(redacted)…hod%3DPAYPAL%26redirect%3Dmobile#/checkout/pageAddCard/addCardFlow/addCard'. The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor is it processing a user gesture. See https://www.chromestatus.com/features/5851021045661696.
findWindowAndRedirect @ main.js:21966
This seems to break the ability to log in on My3 (https://www.three.co.uk/My3Account/Login) in Chrome 56.0.2885.0 canary.
Error:
- Unsafe JavaScript attempt to initiate navigation for frame with URL 'https://www.three.co.uk/My3Account/Login' from frame with URL 'https://sso.three.co.uk/mylogin/?service=https%3A%2F%2Fwww.three.co.uk%2FTh…&resource=portlet'. The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor is it processing a user gesture. See https://www.chromestatus.com/features/5851021045661696.
- Uncaught DOMException: Failed to set the 'href' property on 'Location': The current window does not have permission to navigate the target frame to 'https://www.three.co.uk/ThreePortal/appmanager/Three/SelfcareUk?…'.
After submitting log-in credentials, the user stays on a (now partially blank) login page instead proceeding to the My3 home page.
It still works in Chrome 53.0.2785.143 stable.
I just reenabled this experiment in Chrome 56+ builds (should be on the chrome canary in a day or two) with a few changes to try to make it less breaking:
I still think that the parent frame sending a postMessage should also "activate" the iframe, or there needs to be a way to explicitly allow a child frame to top-nav so without a user gesture. This is an important cross-origin API surface. Iframes are not just ads.
On Wed, Oct 26, 2016 at 12:25 PM natechapin notifications@github.com wrote:
I just reenabled this experiment in Chrome 56+ builds (should be on the chrome canary in a day or two) with a few changes to try to make it less breaking:
- Instead of requiring a current user gesture, a cross-origin iframe can navigation top if it has ever received a user gesture.
- When setting the bit that indicates whether a given browsing context has received a user gesture, it is also set on all of that browsing context's ancestors.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/WICG/interventions/issues/16#issuecomment-256451362, or mute the thread https://github.com/notifications/unsubscribe-auth/ACFbcAuXVIvL28tXEv6TmKkWFK9WGncOks5q36kXgaJpZM4IN2IH .
@hillbrad is it possible for your case to postMessage back to the parent page to do the navigation?
Having postMessage auto-grant this ability would take all the value out of this proposal since postMessage is so widely used.
Maybe we should consider adding a permission that we can delegate down via feature policy (e.g. via an enable attribute on the iframe) to allow the top-level page to say the iframe can navigate it without a user gesture. @hillbrad would that work for your use case?
@ojanvafai an explicit opt-in or callback could work, but there are 7 independent bug reports here, which seems to indicate reasonably wide legitimate use.
What does the data look like on the prevalence of legitimate vs. user-hostile occurrences?
@hillbrad these bug reports were on the less permissive version that required a user gesture for the navigation instead of any user gesture during the life of the frame. It's hard to test all of these because most of them don't link to pages, but I confirmed that the capitalone case does get a user gesture today.
It's very hard to get data on prevalence of legitimate vs. user-hostile at scale. If we could distinguish the two reliably, we'd do a different intervention. :)
If we get reports of real content that breaks with this more permissive solution, we'll need to reconsider.
It seems that any use of hidden frames as an API surface that includes automatic navigation will still break under the new approach because they have no way to collect a user gesture? So I think there should be a way to designate a frame at creation as capable of top navigating, or to decorate a postMessage so it delegates a capability equivalent to a user gesture, before intervening and requiring a larger redesign of these existing uses. Setting up an event listener, parsing and navigating in response to a reply message is not terribly difficult, but it is much more complicated than a simple fire-and-forget postMessage.
On Tue, Nov 1, 2016 at 8:07 AM ojan notifications@github.com wrote:
@hillbrad https://github.com/hillbrad these bug reports were on the less permissive version that required a user gesture for the navigation instead of any user gesture during the life of the frame. It's hard to test all of these because most of them don't link to pages, but I confirmed that the capitalone case does get a user gesture today.
It's very hard to get data on prevalence of legitimate vs. user-hostile at scale. If we could distinguish the two reliably, we'd do a different intervention. :)
If we get reports of real content that breaks with this more permissive solution, we'll need to reconsider.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WICG/interventions/issues/16#issuecomment-257591242, or mute the thread https://github.com/notifications/unsubscribe-auth/ACFbcErrIcZj7CJk4PmxONoJp3niR9dyks5q51W9gaJpZM4IN2IH .
I think a way to delegate top navigation to subframes is reasonable. It would probably build on top of feature policy: https://wicg.github.io/feature-policy/. When we ship feature policy, I don't see any downside to adding the ability to delegate down the ability to do top-navigation without a gesture. But, I'm hesitant to block shipping this until then due to:
I do think we might want to explore having a postMessage that happens during a user-gesture grant the messaged-frame the ability to top-navigate since we pass the user gesture bit with the postMessage already (e.g. the inner frame's message handler can open popups, etc). That'd probably be good for keeping the platform simple and consistent. But, I think that doesn't actually address your need @hillbrad, right?
If you can track a user gesture in a parent frame leading to an postMessage to the child frame and carry the user intent flags through, that should work for my specific use cases. But it would definitely be nice to have something deterministic to set so every postMessage API documentation doesn't need an extra page of explanation about this behavior.
On Tue, Nov 1, 2016 at 11:33 AM ojan notifications@github.com wrote:
I think a way to delegate top navigation to subframes is reasonable. It would probably build on top of feature policy: https://wicg.github.io/feature-policy/. When we ship feature policy, I don't see any downside to adding the ability to delegate down the ability to do top-navigation without a gesture. But, I'm hesitant to block shipping this until then due to:
- The large user benefit this has.
- (so far) no complaints of real-world web sites breaking.
- The restriction can be worked around via a postMessage to the parent.
I do think we might want to explore having a postMessage that happens during a user-gesture grant the messaged-frame the ability to top-navigate since we pass the user gesture bit with the postMessage already (e.g. the inner frame's message handler can open popups, etc). That'd probably be good for keeping the platform simple and consistent. But, I think that doesn't actually address your need @hillbrad https://github.com/hillbrad, right?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WICG/interventions/issues/16#issuecomment-257653733, or mute the thread https://github.com/notifications/unsubscribe-auth/ACFbcA9bW9ghj0R0rZqmkdkr06UgsBH3ks5q54YRgaJpZM4IN2IH .
I'm seeing this in Chrome 56 (dev release), but not for post message. Does anyone know if this will definitely ship on January 31st? I am not familiar with the Chromium release cycle, and whether dates are strictly followed.
@limpygnome the dates aren't strictly followed, but it should ship on January 31st give or take a week. Is this breaking a page for you?
In our facebook application we can not redirect pages using top.location.href any more in chrome v56 beta. It worked fine in previous version.Now javascript error is coming-The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor is it processing a user gesture.
https://apps.facebook.com/candycrush is broken on first install https://apps.facebook.com/candycrushsoda is broken on first install https://apps.facebook.com/livepool/ is broken on first install
I have several applications that I work with that will be broken with this new feature. We have requirements for us to send users out to external websites and redirections. Why would you block an internal application from making decisions about where it should go?
In software if you don't provide a way for either a sub-element to communicate with the parent to help make informed decisions, or allow the child element to make a decision, you're in essence making the child restricted to basically a small task. There are many situations where the child is better suited to make decisions related to the situation it is being used and is basic to decomposing systems. Almost like inheritance, and saying the inherited element is allowed to only do a couple of things, but you can't add functionality.
Also note that many systems have clearly been built using iframes as modular breakdowns. Hopefully this feature will be augmented or an api will be added allowing the child frame to communicate with the parent otherwise I forsee chrome being an issue for many users moving forward.
an api will be added allowing the child frame to communicate with the parent
This sounds like the already-existing postMessage API
Valid point, looks like the postMesage API could be used to accomplish the issue. Of course means the parent frame would need to add a listener to the events. Thank you for the reference.
@tonygaillard this looks like a separate bug. Those apps are broken with this change disabled as well. Filed crbug.com/674229 to track that.
@uofifox sounds like your issue is resolved?
Well I would prefer the feature not get implemented as opposed to saying my issue is resolved. In my case it's great there is a workaround but as I don't have control over the main frame it means we have to ask for feature enhancements which take time to implement
What is a "user gesture"?
User initiated action
@uofifox Nope, this is this bug/feature, because the redirection in JavaScript is not allowed. Go to either one of the application and open the developer console to notice the issue.
This is impacting a site of mine as well, which has an iframe-based login page. We do a login in the iframe via SAML (don't ask), and then on completion, a postMessage to signal the parent to navigate, which fails under the new rules. This is on the same root domain (different subdomains). I'd be OK with a frame-level setting to enable the behavior, or enabling via postMessage.
This issue also impacts the use of the SecureFrame payment api from SecurePay. After payment is made, SecurePay is meant to redirect to a url on your site to notify your application of successful payment. This never happens and results in payments being made without the application knowing about it (reconciliation nightmare).
I have pointed this out to the SecurePay devs, who say they will monitor this feature.
SecurePay SecureFrame integration guide for reference: https://www.securepay.com.au/_uploads/files/SecureFrame_Integration_Guide.pdf
This also breaks login flows for Microsoft Office Online. Example flow:
Here's some documentation on how that flow works: https://wopi.readthedocs.io/en/latest/scenarios/business.html#validating-edit-capabilities
We see two workarounds right now:
If you'd like to discuss this in email, my email address is my username at microsoft.com.
Working on a related effort #42: "Require a user gesture for sandboxed iframe w/ 'allow-top-navigation' to navigate the top-level page" which has a similar purpose as this one but covers different use cases and might break less pages and thus less risky. Any concern about it?
@lubin2010 - thanks, no immediate concerns as I don't think any hosts load our apps via sandboxed iframes, and if we do find issues the workaround is clear.
@ojanvafai yes, this breaks our payment pages for an iframe integration, whereby it needs to redirect the parent page. Our product processes a large volume of transactions for tier one/two merchants, so we're watching this closely and releasing a fix before the scheduled Chromium release date.
For now we've fixed it using post message, tested against Chrome 56 dev. This does not require any user interaction. Would this work-around be broken in the future?
Shopify's embedded app SDK requires top level navigation with window.top.location.href during OAuth. This is similar to Facebook's SDK and many other platforms that assume this functionality -- this change will break logins on a lot of platforms.
This is a reasonable change (to prevent malicious ads) but it should be delayed and at least have a deprecation warning that Chrome developers (non-Canary) would see. That'll give developers more time to come up with other approaches.
@jerodvenemafm I don't quite understand your example. postMessage to the parent and then the parent navigating the top-level page should be unaffected by this change. Do you have a page you can point us to so we can understand what's going on?
@elexisvenator can you point to an example that breaks? Reading through the pdf it seems like the user would be require to interact with the frame?
@limpygnome using postMessage should be totally safe. The point of this change is to make it so that the top-level page is in control of navigations. If the top-level page does the navigation in response to a postMessage, then it's still in charge. :)
@Hammadk, do you have a page you could link us to that we can test?
For now, I think we'll probably change Chrome to show a console warning instead of blocking while we evaluate our options here. Thanks all for the feedback! In general, pointing us to actual sites that break is most helpful because then we can try our best to design solutions that don't break them whenever possible.
URL is private. But it's part of the login process.
Iframe login->POST->successful login->postMessage to parent->parent redirects
The iframe resides on a different sub-domain than the main app.
Thanks Ojan. Shopify's apps are private and available to merchants with online stores. If you have trial store, you can install embedded apps to test this change: https://YOUR-SHOP.myshopify.com/admin/apps/shopify-widgets
If you don't have a Shopify store, our setup is pretty similar to Facebook apps. You can test this change by installing a Facebook app: https://apps.facebook.com/livepool/
Ojan, The last step of the SecurePay payment process is to confirm payment via clicking a button. This redirects the iframe to a "payment is processing" page which after a while redirects the parent to the payment complete page. It is this last redirect that appears to fail.
As for examples, I am afraid our application doe not have any publicly accessible sites with the test payment interface configured. Securepay also does not appear to have a public demo. An example of an actual live site would be https://shopmate.auspost.com.au/ (auspost is their parent company).
:-1: :-1: This change appears to be causing a lot of breakage in my end-to-end Selenium/WebDriver because a lot of the interaction is not treated as user-initiated.
@ojanvafai unfortunately we've had a few issues with using an alternative in such a short time period.
Can you definitely confirm whether Chrome 56 will be changed to feature a console message instead? I think we're still seeing the blocked behaviour on dev.
@limpygnome AFAIK, yes. The code was submitted and will be merged in Chrome 56: https://bugs.chromium.org/p/chromium/issues/detail?id=678328
Thanks for all the bug reports. We're working on reverting it in Chrome 56 and are working on a slightly more permissive solution for Chrime 57.
For those of you who have commented on breakage, since we can't test sites we don't have access to, it would be really helpful if you could tell us if proposed next attempt will still break your pages. Also, we should have it behind a flag in a week or two for you to test.
The Chrome 56 behavior requires the document to have ever had a user gesture. Which means that the bit is lost when the iframe is navigated. For Chrome 57, we're going to try the same thing, but will make it only require that that iframe had a user gesture ad some point. Namely, it will survive navigations in that iframe.
This will still break cases where an iframe is completely hidden from the user and the user never clicks or types in it.
Incidentally, I ran into https://news.ycombinator.com/item?id=13356074 today as an example of the sort of problem this change will mitigate.
since we can't test sites we don't have access to
Here's one that should be easy to test: https://www.twitch.tv/products/bits/B018WMZN5E
UI path to that URL:
Unsafe JavaScript attempt to initiate navigation for frame with URL 'https://www.twitch.tv/products/bits/B018YYYYYY?tv=eyJraWQiOiJjb20uYW1hem9uL…BlvswUhD7tKzLMVWz91pSgc_mvfn0id23MY2w' from frame with URL 'https://twitch.amazon.com/checkout/summary?embed=true&asin=B018YYYYYY&tuid=eyJraWQiOiJjb20uYW1hem9uL…BlvswUhD7tKzLMVWz91pSgc_mvfn0id23MY2w'.
Here is the eBay Checkout flow that was broken in Version 56.0.2924.51 beta (64-bit) - before this change was reverted recently.
1) Go to ebay (www.ebay.com) and sign in 2) Buy any item to get to checkout page. I used item id 121409414417
http://www.ebay.com/itm/eBay-Mobile-QA-10-0-Test-Item-12-/121409414417
3) In Checkout page, click on PayPal or PayPal Credit to open the PayPal sign-in layer 4) Without logging into PayPal, close the PayPal layer that came up 5) The Unsafe JS error shows in console log. User is stuck with the page mask, unable to use the page 6) User refreshes eBay checkout page but user is NOT signed into PayPal 7) User who wants to pay with PayPal is now stuck in infinite loop
Thanks.
This also breaks WeChat OAuth login flows. Example flow:
POC:
success() {
window.top.location = redirect_url
}
Do you have any detail around how this will be more "permissive" in Chrome 57?
Will the "more permissive" version come in version 57 still? If so, when will we get a beta version to test?
We are seeing a lot of ads that navigate the top-level page outside of a user gesture. We think this is user hostile and that we don't lose any important use cases by requiring a user gesture. Chrome has added formal measurement for this. Once we get the numbers back, we plan to make this change.
There is also the allow-top-navigation flag for iframe sandbox attribute. Once we make this change the plan is that sandbox disallows top navigation and allow-top-navigation allows the behavior described above (i.e. even with allow-top-navigation, you'd still need a user gesture to navigate the top-level page).