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

Fixed external links in the viewer iframe #944

Closed
wants to merge 2 commits into from

Conversation

veloman-yunkan
Copy link
Collaborator

Fixes #943

Before this fix clicking an external link in the viewer iframe had no effect (other than an error being reported in the browser dev tools console) because the attempt to navigate the top browser context was suppressed due to sandboxing.

One downside with this solution is that it again opens the possibility of losing the viewer toolbar if an internal link in a ZIM file has its target attribute set to _top (however, such links can be detected and corrected by the viewer). I cannot think of other downsides.

Before this fix clicking an external link in the viewer iframe had no
effect (other than an error being reported in the browser dev tools
console) because the attempt to navigate the top browser context was
suppressed due to sandboxing.
@veloman-yunkan
Copy link
Collaborator Author

@rgaudin @kelson42 I've tested this PR but expect you to try it too

@kelson42
Copy link
Collaborator

kelson42 commented May 3, 2023

@veloman-yunkan Seems to work fine on FF 111, but reopening the problem with _top target is not acceptable IMO

@mgautierfr
Copy link
Member

I agree with @kelson42. I have the feeling that this PR negates the initial purpose of sandboxing. It was never to add safety but to avoid zim files breaking navigation by changing _top.

@Jaifroid
Copy link
Member

Jaifroid commented May 3, 2023

See https://caniuse.com/?search=allow-top-navigation-by-user-activation. The one browser you might be concerned by is Safari on iOS (e.g. iPad), where this workaround wouldn't work. It also wouldn't work with IE11, but I guess that's less of a concern nowadays.

Comment on lines +269 to +270
} else {
target.setAttribute("target", "content_iframe");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is nice.
I even wonder if you would have done this at first instead of introducing complex sandboxing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the sandboxing was necessary to prevent scripts in the ZIM accessing external resources ("phoning home") -- a real issue with Zimit ZIMs -- and also to prevent top-level navigation. We tried lots of combinations...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah yeah, but I think is better for us to don't count the time we have spend on this 😉


Maybe (as almost all the time), the best would have been to fix the root cause and fix the generated zims.
After all, the SW embedded in the zim files is able to catch a request to www.foo.com/bar and do a request to /A/www.foo.com/bar instead. We could (and can) make the SW refuse request to unhanded url.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sandboxing was needed to prevent programmatic escape from the iframe (see kiwix/kiwix-tools#604). Unfortunately this trick doesn't work perfectly in Chromium

@veloman-yunkan
Copy link
Collaborator Author

I agree with @kelson42. I have the feeling that this PR negates the initial purpose of sandboxing. It was never to add safety but to avoid zim files breaking navigation by changing _top.

I tried to fix the concern with target="_top" links (see the fixup commit). Though it worked in Firefox, unfortunately it was a little short of working in Chromium (v90).

The attached ZIM file demonstrates the problem.

There are two pages. Either page contains a link to the other page with target set to _top. Also the pages contain javascript code that tries to break out of the iframe with some delay (without any user interactions). The delay for the first page is 5 seconds, and for the second page - 1 second.

Neither page can break out of the iframe when loaded in the viewer by specifying its URL in the address bar (e.g. http://localhost:8080/viewer#naughty/naughty.html or http://localhost:8080/viewer#naughty/naughty2.html). Clicking the links also prevents the escape attempt by the links themselves. However the link from the first page to the second page enables the javascript breakout attempt (with short delay) to succeed!

Note again that such behaviour is specific to Chromium (at least v90) and not to Firefox (at least v112).

@veloman-yunkan
Copy link
Collaborator Author

See https://caniuse.com/?search=allow-top-navigation-by-user-activation. The one browser you might be concerned by is Safari on iOS (e.g. iPad), where this workaround wouldn't work. It also wouldn't work with IE11, but I guess that's less of a concern nowadays.

@Jaifroid Thanks for pointing out this shortcoming of this approach. I found another one before seeing your comment. It looks like we have to abandon this PR but at least it was worth a try.

@veloman-yunkan
Copy link
Collaborator Author

Replaced by #946

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

External content is inaccessible in the viewer iframe
4 participants