Last modified: 2014-06-20 22:47:21 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T65445, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 63445 - security review of Flow's templating
security review of Flow's templating
Status: NEW
Product: MediaWiki extensions
Classification: Unclassified
Flow (Other open bugs)
master
All All
: High normal (vote)
: ---
Assigned To: Chris Steipp
:
Depends on: 66094
Blocks: 63443
  Show dependency treegraph
 
Reported: 2014-04-02 20:08 UTC by spage
Modified: 2014-06-20 22:47 UTC (History)
4 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description spage 2014-04-02 20:08:02 UTC
Quick sketch:
Flow's new front-end will be using handlebars.js on the client to render templates supplied by ResourceLoader, and lightncandy in PHP to render the same templates pre-compiled at commit-time.

No code in gerrit yet.
Comment 1 Chris Steipp 2014-04-07 17:57:41 UTC
Let me know when you have code ready.

Also, please follow my suggestion about policy here https://www.mediawiki.org/wiki/Requests_for_comment/HTML_templating_library#Security, and make sure the team has a policy that,

* If substitutions are used in html attributes, those attributes must be quoted with double quotes.
* Make sure any SafeString objects have their escaping as close to the creation of the SafeString as possible, and that should be as close to the output as possible. It would be really helpful if I don't have to trace back more than 1 (or at most 2) function calls to see the escaping.

What is the timeline around this?
Comment 2 spage 2014-06-06 00:21:43 UTC
Hi Chris!  We aim to merge the new Flow frontend in two weeks.

The code is in the Flow frontend-rewrite branch.
* It depends on the new Mantle extension for the third-party JS library HandlebarsJS, in Mantle/javascripts/externals/handlebars.js. Mantle also has ResourceLoader and JS code to use this templating library from MobileFrontend. The Mantle extension is ready for review, bug 66094.
* The third-party PHP library lightncandy is in Flow/vendor/lightncandy.php.
* The way Flow invokes templates from PHP code is set. Shahyar Ghobadpour is refining declarative ways to invoke templates from JS code. We have a small set of helper functions that templates can invoke.

Some documentation of our approach is at <https://www.mediawiki.org/wiki/Flow/Templating>.  Note we disable run-time server compilation to PHP in production, instead we compile handlebars templates to PHP in advance and check them into git. Handlebars templates can similarly be compiled to JS in advance, but we aren't planning that initially (bug 64735) and the user's browser will compile them to JS at runtime.

I'll pass on your comment #1 suggestions to the Flow team.
Comment 3 Chris Steipp 2014-06-20 01:33:11 UTC
I'm still working on the review, but a couple of comments:

In includes/TemplateHelper.php
* getTemplateFilenames() should check for directory traversal
* progressiveEnhancement() should escape $insertionType and $sectionId
* Can you whitelist function names in pipelist, eachPost? 
* diffRevision: update @param comments to indicate diffContent isn't escaped
* Seems like addReturnTo shouldn't setup the parameters if the request was a POST

* flow_block_header.handlebars and flow_block_header_single_view.handlebars assume revision.content is safe html. flow_preview.handlebars assumes content is safe. It's hard to find where I can prove that-- maybe add a comment in the template to where that is generated, so it's easy to check the correctness?

* form_element's setting the {{tag}} seems like it could be abused. Maybe adding a comment that it really shouldn't be used except in FlowHandlebars.prototype.formElement, and having the default in the switch raise an exception or reset tag to a sane value?
Comment 4 Erik Bernhardson 2014-06-20 18:43:04 UTC
In includes/TemplateHelper.php
> * getTemplateFilenames() should check for directory traversal

new patch: https://gerrit.wikimedia.org/r/140938

> * progressiveEnhancement() should escape $insertionType and $sectionId

new patch:  https://gerrit.wikimedia.org/r/140940

> * Can you whitelist function names in pipelist, eachPost? 

pipelist turns out to be unused, removed: https://gerrit.wikimedia.org/r/140943

eachPost (and two new block helpers, ifEquals and ifAnonymous) can't be directly whitelisted.  Basically lightncandy takes this syntax:

    {{#eachPost foo}}
        ...
    {{else}}
        ...
    {{/eachPost}}

The first ... gets converted into a closure as $options['fn'] and the second ... after the {{else}} gets converted into a closure as $options['inv'].  The block helper then decides based on parameters to call those functions one or more times.

I suspect your primarily worried about users being able to specify the function that is called through a tainted variable.  To prevent this i've added a patch which ensures these callbacks are Closure instances which cannot be directly provieded by user input.

new patch: https://gerrit.wikimedia.org/r/140944
 
> * diffRevision: update @param comments to indicate diffContent isn't escaped

@TODO

> * Seems like addReturnTo shouldn't setup the parameters if the request was a POST

@TODO

> * flow_block_header.handlebars and flow_block_header_single_view.handlebars assume revision.content is safe html. flow_preview.handlebars assumes content is safe. It's hard to find where I can prove that-- maybe add a comment in the template to where that is generated, so it's easy to check the correctness?

Matt also noticed this problem,  the following patch makes the decision of to escape or not escape revision content more specific with less assumptions.  Perhaps the comments between me and matt on PS2 also make it more clear how this should work.

new patch: https://gerrit.wikimedia.org/r/140831/

> * form_element's setting the {{tag}} seems like it could be abused. Maybe adding a comment that it really shouldn't be used except in FlowHandlebars.prototype.formElement, and having the default in the switch raise an exception or reset tag to a sane value?

form_element looks to be unused, removed here: https://gerrit.wikimedia.org/r/140957


There are still two aboved marked as todo, i need to check with another flow dev about those.
Comment 5 Erik Bernhardson 2014-06-20 18:59:20 UTC
> * diffRevision: update @param comments to indicate diffContent isn't escaped

new patch: https://gerrit.wikimedia.org/r/140962
Comment 6 Chris Steipp 2014-06-20 22:47:21 UTC
Thanks for the quick fixes Erik!

I've looked through the majority of the rest of the template handling, and I don't see anything that makes me too nervous.

Architecturally, I think with just a little cleanup, this could be a good addition in core. But that's probably a discussion for another time.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links