Page MenuHomePhabricator

Safely embeddable JavaScript plugins/extensions/gadgets (wmhack2016 session)
Closed, ResolvedPublic

Description

Would be great to have a safer system for embedding JavaScript plugin/extension/gadgets/tools into the MediaWiki interface.

Pull some old iframe-embedding ideas from https://www.mediawiki.org/wiki/Extension:EmbedScript ?

Session notes: https://etherpad.wikimedia.org/p/WikiHack16-JavaScript

Event Timeline

brion created this task.Apr 1 2016, 8:17 AM
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptApr 1 2016, 8:17 AM
brion added a comment.Apr 2 2016, 12:23 PM

Existing related project https://commons.wikimedia.org/wiki/Commons:WikiProject_WikiWidgets -- we'll work on porting some of those examples together soon :)

Sophivorus added a subscriber: Sophivorus.EditedApr 2 2016, 12:25 PM

Two more related projects:
https://www.mediawiki.org/wiki/Extension:WikiWidgets (not related to the WikiWidget project at Commons) - Recently archived
https://www.mediawiki.org/wiki/Extension:Widgets + http://www.mediawikiwidgets.org/

brion added a comment.Apr 2 2016, 5:12 PM

Sample graph plugin is available for Wikidata, will be cleaned up later and others added!

Standalone version: https://rawgit.com/brion/mw-js-plugin/master/wiki-side/index.html

Login to Wikidata and go to your user common.js page. Click 'edit' tab and paste in:

importScriptURI('https://www.wikidata.org/w/index.php?title=User:Brion_VIBBER/plugin-test.js&action=raw&ctype=text/javascript');

This shows an entity graph using vis.js at the top of entity pages on Wikidata. You can drag the nodes around to show off the cute vis library's physics effects :) or click on one of the associated nodes to navigate to that item.

The actual plugin is loaded entirely within the iframe, off of github (via rawgit.com to fix the mime type on the index.html), and the plugin has no direct access to the rest of the page. With some more iframe sandbox options, this should be even safer. :)

A very limited frame<->parent event-based API is implemented which allows the host wiki to send the current page title down to the plugin, and the plugin to request the wiki navigate to another page -- but only another wiki page, not any arbitrary URL.

There are thee major avenues for further exploration:

  • want a MediaWiki extension providing user-friendly registration of plugins. Might want to examine also the state of Gadgets 2.0 before starting in on this!
  • fancier event-based APIs could allow plugins to enhance the user interface of MediaWiki, such as adding tools to the source editor or even VisualEditor. (Add a button which launches the plugin in a dialog, with access for the plugin limited to modifying the editor contents.)
  • with increased safety controls (review and/or better isolation within the plugin iframe) we could provide a safer method for things like the WikiWidgets that have been enabled on a few wikis adding interactive widgets to content
    • one major difficulty here is solving the "web bug problem" -- even in an isolated iframe the JS/HTML can load external image/script/style/media resources which expose the user's IP address to a third-party site. Currently only permission restrictions and review prevent this on MediaWiki:Common.js-based methods like WikiWidgets uses.
    • easy use of offsite resources also encourages breakability -- we would prefer to encourage use of materials within the wiki so we can ensure they are predictably available, freely licensed, not copyvios, etc

Solving the 'web bug problem' is hard but not impossible. A couple of interesting projects:

  • caja uses both a recompiler for JS and some proxies/sanitizers for DOM access. It's less actively maintained than I'd like and the recompiler is Java-based, but is a fairly mature project.
  • jailed uses relatively light source tweaks and either a subprocess (in node) or a web worker (in browser) to further isolate untrusted plugin code from the main context. However, a web worker would not provide any synchronous communications primitives, so proxying to the main context's DOM would not be possible. This would make using standard visualization or UI libraries pretty hard.
brion added a comment.Apr 2 2016, 5:16 PM

For example editor widgets, might try porting the editor dialog for ProveIt.

For content widgets, the Game of Life example on spanish wikipedia article would be awesome :D

brion added a comment.Apr 3 2016, 9:55 AM

Slides for demo:

brion added a comment.Apr 18 2016, 6:57 PM

I've written up some more notes at https://www.mediawiki.org/wiki/User:Brion_VIBBER/Secure_code_modules_through_iframe_sandboxing -- will flesh this into an RFC & evolve the sample implementation a bit over the next few weeks.

This comment was removed by Sophivorus.

Wouldn't CSP deal with web bugs?

brion added a comment.May 1 2016, 12:51 PM

Wouldn't CSP deal with web bugs?

Ah nice, I'll have to read up more and test support. Looks like that should be able to enforce the stuff I want for the 'web bug' problem, as long as non-supporting browsers are locked out... http://www.html5rocks.com/en/tutorials/security/content-security-policy/

Is there a good reason to keep this task open (as Wikimedia Hackathon 2016 is past)? Or does it need adjustment (general task instead of a Hackathon session)?

Aklapper closed this task as Resolved.Nov 26 2017, 1:20 PM

No reply by @brion, hence closing.