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

ZeroClipboard doesn't work in JsFiddle #511

Closed
loganvolkers opened this Issue Nov 7, 2014 · 23 comments

Comments

@loganvolkers
Copy link

loganvolkers commented Nov 7, 2014

We've been using JsFiddle for a long time and recently it seems to have stopped working when embedded in a JsFiddle iframe.

We're naturally curious to see why this has regressed, so we made a test case.

In an iframe it appears that flash has been disabled by JsFiddle:

{"type":"error",
"name":"flash-disabled",
"target":null,
"relatedTarget":null,
"currentTarget":null,
"timeStamp":1415318935611,
"message":"Flash is disabled or not installed",
"minimumVersion":"11.0.0"}

Directly visiting the page seems to work just fine

{"type":"ready",
"target":null,
"relatedTarget":null,
"timeStamp":1415319109675,
"message":"Flash communication is established",
"version":"15.0.0"}
@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Nov 7, 2014

For me, even the latter link didn't work (in Chrome). What browser were you using, @loganvolkers?

I can't think of anything that I've changed that would make it break, so I suspect the problem is on JSFiddle's side. Can you try it with an older version of ZeroClipboard to see if that works? I'm guessing not from what I'm seeing.

What I see from observing Chrome's chrome://net-internals tool is that JSFiddle appears to be preventing the request for the SWF from even being made. I have no idea how they would achieve this... but that seems to be the case.

Here's the related traffic in Chrome I see for:

 1. http://jsfiddle.net/loganvolkers/koa04mju/ (edit view):

image
 2. http://fiddle.jshell.net/loganvolkers/koa04mju/show/ (result view):

image
 3. http://zeroclipboard.org/

image

Granted, zeroclipboard.org does not use iframe elements but I'm not yet sure if that's the issue either so much as whatever JSFiddle is doing... but it certainly could be.

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Nov 7, 2014

Old versions of ZeroClipboard aren't working for me in JSFiddle now either, even in existing fiddles that I know used to work. Tried in both Chrome and Firefox on Mac.

@zalun

This comment has been minimized.

Copy link

zalun commented Nov 7, 2014

When did it changed?
Something like a few weeks ago? Or just now?
We are definitely not blocking any flash by choice.
sandbox for iframe is sandbox="allow-forms allow-popups allow-scripts allow-same-origin"

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Nov 9, 2014

@zalun: I'm guessing a few weeks ago but I didn't see it happen till @loganvolkers reported.

@loganvolkers: Do you recall when you first noticed that ZeroClipboard/Flash fiddles stopped working?

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Nov 21, 2014

@loganvolkers @zalun: Any updates?

@loganvolkers

This comment has been minimized.

Copy link

loganvolkers commented Nov 21, 2014

I first noticed this sometime in the past couple months. Haven't been able to discover the root cause, but it still appears to be an issue.

I also have an unconfirmed report that this also affects codepen.io

@thomasgrant

This comment has been minimized.

Copy link

thomasgrant commented Nov 25, 2014

I've just run into this problem myself while attempting to use version 2.1.6 on both jsFiddle and Codepen. I'm doing some troubleshooting of my own as it appears what's been listed here is a bit incomplete and inconclusive. I'd like to lend aid to the issue.

@loganvolkers mentions that the page linked at http://fiddle.jshell.net/loganvolkers/koa04mju/show/ does not use an iframe and the plugin works. First, when inspecting the page, I see that this page DOES use an iframe. Second, I've just tried this page in both Chrome 39.0, Firefox 29.0.1 and Internet Explorer 11 on Windows Server 2008 R2 with Flash 15.0.0.239 installed. It does NOT work in all three browsers and I receive differing results from the event.

Firefox 29.0.1 & Internet Explorer 11:

{"type":"error",
"name":"flash-disabled",
"target":null,
"relatedTarget":null,
"currentTarget":null,
"timeStamp":1416953961971,
"message":"Flash is disabled or not installed",
"minimumVersion":"11.0.0"}

Chrome 39.0:

{"type":"error",
"name":"flash-deactivated",
"target":null,
"relatedTarget":null,
"currentTarget":object#global-zeroclipboard-flash-bridge,
"timeStamp":1416953961971,
"message":"Flash is too outdated for your browser and/or is configured as click-to-activate",
"minimumVersion":"11.0.0",
"version":"15.0.0"}

First, this event result does not rendered to the page itself. I pulled this from the console. Notice that the value for keys "name", "currentTarget" and "message" are different from what's displayed for Firefox and Chrome. There is also an addition key of "version" included.

Also shown in the console is the following warning. I assume this is related to the event result not being rendered in the page.

Uncaught TypeError: Converting circular structure to JSON
@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Nov 26, 2014

My own results were pretty much in line with @thomasgrant's.

The circular reference error is from trying to JSON.stringify an event object with an Element reference in it (which have many types of circular references like el.ownerDocument.defaultView.document.defaultView....), nothing specific to ZeroClipboard.

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 1, 2014

I wonder if this is actually a bug in Flash Player 15 having issues with iframes? It seems to affect pretty much every browser and at least 2 popular and high traffic developer websites.

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 1, 2014

@loganvolkers @thomasgrant @zalun: Can any of you give it a try using an older version of Flash Player, i.e. 14.x?

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 1, 2014

I tried using Flash Player 14.0.0.176 (NPAPI) in Google Chrome 39 on Mac OSX 10.9 with the following forked JSFiddle: http://jsfiddle.net/JamesMGreene/jhmt9808/

I continued to receive the same types of errors. I don't have time to test any older versions of Flash than that right now.

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 1, 2014

Possibly related bugs for Chrome (but why doesn't it work in all the other browsers!?!?!?):

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 2, 2014

I did some more testing on a local page of my own. If I use an iframe with the same attributes as JSFiddle, I can reproduce the same problem. If I remove the iframe element's sandbox attribute altogether, then everything works fine.

It appears to be a conflict with the sandboxed plugins browsing context and the plugin apparently being unable to identify itself as "secure".

Conversely with this supposed claim of a plugin possibly being able to be loaded if it somehow identifies itself as "secure", in an HTML5Rocks article on iframe sandboxing, it claims that plugins will simply never work within a sandboxed iframe because they are, by definition, un-sandboxed native code. Personally, this explanation makes more sense to me.

Soooooooo....

@zalun: Would it be possible to:

  • Have a JSFiddle fiddle config options to not sandbox the iframe?
  • At the very least, to not forcibly add the iframe when trying to view the frame contents URL directly?
@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 2, 2014

FYI, I sent an email to the WHATWG mailing list to confirm this situation as reality (and indeed it is).

Archived email thread: http://lists.w3.org/Archives/Public/public-whatwg-archive/2014Dec/0002.html

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 3, 2014

Some test results for trying to probe for this state:

JamesMGreene added a commit to JamesMGreene/zeroclipboard.github.io that referenced this issue Dec 8, 2014

JamesMGreene added a commit to JamesMGreene/zeroclipboard.github.io that referenced this issue Dec 8, 2014

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 8, 2014

Alright, so I built my own little iframe sandboxing analysis page(s):
    http://zeroclipboard.org/test-iframes.html

The results are pretty interesting as they show that there is one reasonable workaround that can be employed to get ZeroClipboard working again in JSFiddle/CodePen:

  1. From the child frame's window, get window.frameElement (the iframe element used by the parent window)
  2. Store its sandbox attribute value
  3. Remove its sandbox attribute ⚠️
  4. Use ZeroClipboard as normal and get all of your elements clipped (which will instantiate the Flash plugin)
  5. Theory: Add the sandbox attribute back with its original value — unless it turns out that this will destroy/disable the Flash plugin that we've instantiated... in which case, just skip this step. 💀
@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 8, 2014

P.S. That workaround only works in the frame is of the same origin, so, with JSFiddle, you would still also have to open the page via its fiddle.jshell.net domain rather than jsfiddle.net. 😢

@zalun

This comment has been minimized.

Copy link

zalun commented Dec 9, 2014

thanks for the analysis, I'll check this out tomorrow ... sandboxing is a must (at least for now)

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 9, 2014

Sure.

That said, any iframe with the same domain and a sandbox attribute including both allow-scripts and allow-same-origin basically doesn't offer any real security since from child can just remove the sandbox attribute and run amok:

window.frameElement && window.frameElement.removeAttribute("sandbox");

You would need to remove allow-same-origin to achieve a secure sandbox, AFAIK, but that has other ramifications.

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 15, 2014

Planned Resolution

Inside of ZeroClipboard:

  • Extract the semi-reusable code from the analysis work and pin-point the cases that matter to ZeroClipboard as a library.
  • Add a sandboxed state tracking property (tri-state Boolean) into the _flashState object.
  • Run the analysis both when ZeroClipboard is initially loaded and at the start of every call to _create (ZeroClipboard.create).
  • Introduce new error event for when we are 100% certain that we are executing with a sandboxed iframe: error[name="flash-sandboxed"]
  • Update the documentation to add a section devoted to explaining sandboxed iframe's impact on the native plugins (and thus Flash, and thus the ZeroClipboard library), mentioning JSFiddle and CodePen as example problematic setups
  • Update the documentation to detail the aforementioned new error[name="flash-sandboxed"] event
  • Update the documentation for the existing error[name="flash-disabled"] and error[name="flash-deactivated"] events to mention that they may also occur if executing within an undetectable sandboxed iframe

Outside of ZeroClipboard:

  • Create a "starter" JSFiddle (related no-longer-functioning-due-to-sandboxing PR #347) that hacks the sandbox attribute and adds a link to viewing the fiddle itself via its fiddle.jshell.net address (the link will not be clickable until the sandbox is removed, though, as the JSFiddle sandbox does not include allow-top-navigation). Hacking the sandbox attribute meaning one of the following, in preference order:
    1. Duck-punching ZeroClipboard.create to remove it and add a listener to readd it after the Flash movie has loaded/erred (assuming Flash still works cross-browser after readding the sandbox)
    2. Duck-punching ZeroClipboard.create to remove it (pre-execute) and duck-punching ZeroClipboard.destroy to readd it (post-execute)
    3. Just removing the it altogether and leaving it off... yay for unfortunate security loopholes
  • Create a "starter" CodePen that includes a link to view the pen itself via its s.codepen.io address (the link will not be clickable while viewing the sandboxed iframe, though, as the CodePen sandbox does not include allow-top-navigation). Unlike JSFiddle, CodePen does not re-frame the sandboxed contents if viewed directly.
@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Dec 24, 2014

FYI, moved my iframe sandboxing analysis page over to a separate project (sandblaster.js) that spun off from my research into this issue:
    http://jamesmgreene.github.io/sandblaster/test-iframes.html

JamesMGreene added a commit to JamesMGreene/zeroclipboard that referenced this issue Dec 29, 2014

Flash: Add support for sandbox detection
Also adds new event: `error[name='flash-sandboxed']`

Ref zeroclipboard#511
@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Jan 1, 2015

I've done all I can for this issue now. The sandboxing is a huge PITA but it's nothing that we can expect to go away as it adds very legitimate value for the various playground sites that employ it.

@JamesMGreene

This comment has been minimized.

Copy link
Member

JamesMGreene commented Jan 1, 2015

P.S. Link to documentation on "starter snippets": docs/instructions.md#starter-snippets-for-playground-sites

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment