Script iframe sandboxing example

Sat down for a few hours to put this together. It’s a bit rough, but it gets the concept across. let me know if you have any additional thoughts (manly from the devs’ side).


Quick afterthoughts:

In the real version, the window.postMessage calls would be abstracted away, so you would simply call game.get_full_sequence(0), or API.getMessages({size: 1, skip: 0}), and that would get translated into the postMessage (obviously with something to deal with the asynchronous nature of postMessage).

Also, if any libraries should be included by default (i.e. The EternaScript API or jQuery), they would be inserted in a script tag in the iframe. To make things simple/less expensive, you could even adjust the EternaScript editor to allow you to choose which you want (a la jsfiddle or something similar).

It is worth nothing that the sandbox attribute is newer and not supported in legacy browsers. It would be wise to detect the user’s browser version before embedding the code, and not allowing scripts to run (requesting a browser upgrade), or at the VERY least putting up a warning at that point. We would also need to keep close tabs on vulnerabilities with the sandbox attribute.

@LFP6:  I think the goal – allowing players to execute other player’s boosters without introducing new security concerns (and hopefully, removing some existing ones) – is really important. Thank you for putting this together.

I don’t feel like I’m in a position to really evaluate the technical merits of your script. Can you summarize the key objectives you’ve addressed, and what would be needed to flesh it out to useable code?

@Nando, to what extent does this address your concerns?

What this script has addressed:

  • Constraining the script to run in a sandboxed iframe, preventing the script from modifying the entire page, or accessing sensitive APIs

  • Exposing a basic API for access to Eterna data and the Flash game

  • Providing a rudimentary means for scripts to request access to sensitive APIs for the user
    What still needs to be handled:

  • Adding all the individual APIs that need to be accessed

  • Creating wrapper functions for the APIs so that it’s more straightforward to use (IE you’re actually calling Game.get_sequence() instead of constructing a postMessage call)

  • Creating a polished implementation of the permissions interface, both deciding what the permissions should be and creating some interface more akin to Google’s than just an alert like I’m using now (probably some sort of modal window, maybe like the overlay/event thing I’ve seen around Eterna lately)

  • Actually implementing it in the existing code, including handling timeouts/libraries (specifically the “Script API”)

  • Figuring out where the iframe is for boosters (IE, should it be some resizable overlay window?  append to the bottom or side, and shrink the applet height/width? allow the developer to choose?), and possibly look into an alternative for the classic EternaScript interface if the developer wanted to have more real estate than just the result box (ie, the frame could be placed in a modal, though this can probably wait)

  • Determine if the user’s browser supports iframe sandboxing, and probably make sure there’s no known vulnerabilities in the browser being used, and at least provide a prominent security warning if either of these conditions fail.
    None of these are particularly difficult, it’s pretty much all detailling, and all of them I could probably even do myself with input from the devs, minus implementation, unless we can get the script interface code updated

1 Like

Re “preventing the script from modifying the entire page”:  It seems this would work against using the booster framework to evolve the game UI.  Could the flash app be moved inside the sandbox, with the iframe being the entire (visible) page?

That was my point with “Figuring out where the iframe is for boosters”

Would there be any reason why we couldn’t limit it to a sidebar/header/footer or modal? If needbe, we can have another option to set the iframe to be static, 100% width and height, and transparent background. The concern is just making it clear what the “actual” page is vs what the script generates.

My vision for the booster framework is for it to provide the mechanism for players (including those without official developer status) to evolutionary design and develop a new game UI that doesn’t require flash.  (This is well beyond the initial goal for boosters, or the simple boosters we have coded to date.)  If we are going to enable this, the “booster” needs to keep full control of the visible page, including the flash applet.  It might, for example, want to overlay the flash UI with something addition, put the flash UI into a slidable frame, of eventually just hide it entirely.

Hence my question of whether there is anything fundamental about your proposal that is incompatible with this vision.

The method I suggested, possibly coupled with a couple minor additional hooks, should do everything you need (new UI could be overlayed, to the side, whatever). It is important to consider that anything inside the iframe should be considered untrusted.

I’m feeling like I may be missing the point of the last sentence.  Just a reminder that the anything in the sandbox, including the flash app itself, would have to use the sandboxed iframe’s parent as a proxy for getting data?  Or something more?

Yes. And actually, I just realized that you can’t load plugins into a sandboxed iframe, so it’s a moot point anyways.

Some additional information:

One thing that could mitigate some issues is if the script was served in an iframe from a separate domain, instead of just sandboxing it, like jsfiddle does. Another possible option would be using a JS interpriter like this one.

1 Like