Safe, Closure-free, Serializable functions

Alex Russell slightlyoff at google.com
Thu Sep 26 11:14:09 PDT 2013


On Thu, Sep 26, 2013 at 9:56 AM, Aymeric Vitte <vitteaymeric at gmail.com>wrote:

>  I would like to defend against a potential mitm/code injection and
> ideally against globals modifications.
>

Only one of those is a threat (MITM). The other is an effect of something
happening (which you may or may not want). Conflating them isn't meaningful.


> Unfortunately I have the ws problem which screw up a little bit the use
> case. So, we have the scenario that you see at the begining of [1], forget
> about the unsafe-inline, I thought it could apply to the worker but it does
> not.
>

Right. Workers are something I've raised with the WebAppSec WG and want to
get a solution for (as I'm leading the design of the Service Worker API:
https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md)


> I tried (as an experiment) to apply this case using CSP and I don't
> understand very well what the result does secure, as well as [2]
>
> Regards
>
> Aymeric
>
> Le 26/09/2013 18:14, Alex Russell a écrit :
>
> It's unclear what your threat model is. What do you want to defend, from
> who or what, and for how long?
> On 26 Sep 2013 00:40, "Aymeric Vitte" <vitteaymeric at gmail.com> wrote:
>
>>  This is similar to the "Native" thread as Andrea mentioned.
>>
>> Then when SES is coming?
>>
>> It seems urgent to boost it, I have tried CSP recently, or at least what
>> works today, see [1] and [2], unfortunately I don't see quite well what it
>> does secure, today and tomorrow.
>>
>> Regards,
>>
>> Aymeric
>>
>> [1]
>> http://lists.w3.org/Archives/Public/public-webappsec/2013Sep/0058.html
>> [2]
>> http://lists.w3.org/Archives/Public/public-webappsec/2013Sep/0067.html
>>
>> Le 26/09/2013 02:32, Mark S. Miller a écrit :
>>
>> Hi François, your goals here have a tremendous overlap with SES. In what
>> ways is SES not satisfactory for these purposes?
>>
>>  The best short-but-accurate summary of SES, sufficient for this
>> question, is <http://research.google.com/pubs/pub40673.html> section 2.3.
>>
>>  SES does not remove eval and Function, but rather replaces them with
>> confining equivalents which should be better for your purposes. You can get
>> SES from either <``
>> https://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/>
>> or <https://code.google.com/p/es-lab/source/browse/trunk/src/ses/>.
>>
>>  The security of SES is analysed at <
>> http://theory.stanford.edu/~ataly/Papers/sp11.pdf>.
>>
>>
>> On Wed, Sep 25, 2013 at 4:29 PM, François REMY <
>> francois.remy.dev at outlook.com> wrote:
>>
>>> Hi,
>>>
>>> TLDR ==> The web needs a way to express executable code that does not
>>> rely on its parent context, is guaranteed to be side-effect-free, and can
>>> be executed safely anywhere (even in a different
>>> thread/worker/window/device, or as callback for browser code being executed
>>> while the DOM is not ready to be accessed)
>>>
>>>
>>> It's been some time I've been working on this idea of a Closure-free,
>>> Serializable function. This kind of function would have no access to the
>>> parent closures they are defined in, and only limited (read-only) access to
>>> the enclosing environment (read-only Math, Object, Array, others...).
>>>
>>> To the difference of other functions, those objects would not be
>>> affected by the JavaScript running elsewhere on the page, so in this
>>> closure-free function, Array.prototype.slice is guaranteed to be the native
>>> slice function, not some kind of polyfill or replaced function.
>>>
>>> |    function sort(array) as serializable {
>>> |        Array.prototype.sort.call(array);
>>> |    }
>>>
>>> |    function sqrt(number) as serializable {
>>> |        return Math.sqrt(number);
>>> |    }
>>>
>>> |    function __BAD_CODE__() as serializable {
>>> |        return new XMLHttpRequest(); // xhr not defined in ES6
>>> |    }
>>>
>>> Trying to export a global variable or modify any of the host
>>> environment-defined objects would fail.
>>>
>>> |    function __BAD_CODE__(number) as serializable {
>>> |        globalNumber = number; // cannot write into the global object
>>> |    }
>>>
>>> |    function __BAD_CODE__() as serializable {
>>> |        Object.prototype.doSomething=function() {}; // cannot write
>>> into the native objects
>>> |    }
>>>
>>> It's also important to note that any Object or Array created inside this
>>> context will be passed to the calling context by deep-cloning (or by
>>> replacing the "safe" Math object by the host Math object of the calling
>>> code in the case of environmental objects). Objects that can't be cloned
>>> (non-serializable functions, for example) are just transformed into null.
>>> We could also maybe use the idea of a proxy though deep-cloning seems safer.
>>>
>>> This makes sure it's impossible to leak the "safe" objects to the
>>> calling context in any way (ie: the calling code can leak anything to the
>>> called code, but not the reverse).
>>>
>>> |    var RealSin = Math.sin;
>>> |    Math.sin=function() {};
>>> |
>>> |    function giveMeMath() as serializable {
>>> |        return [Math, Math.sin];
>>> |    }
>>> |
>>> |    var [m,s] = giveMeMath();
>>> |    // s === RealSin
>>> |    // m === Math
>>> |    // m.sin !== RealSin
>>> |
>>> |    // note that another possibility here
>>> |    // would be to have giveMeMath return [null,null]
>>> |    // (ie: consider host objects unserializable)
>>>
>>> To be honest, those functions are not really meant to expose new
>>> objects: even if they need some internally, they should just keep them
>>> internally and avoid distributing them. The deep-cloning algorithm is just
>>> there for the cases where you want to return multiple values at the end of
>>> a function, or when you need an options object.
>>>
>>> Still, the fact they run in a "safe" environment makes them a good
>>> candidate for further optimization and inlining, so we may end up seeing
>>> codes written as serializable to benefit from performance boost and safety
>>> from external attacks.
>>>
>>> |    function Point(x,y) as serializable {
>>> |        x = +x;
>>> |        y = +y;
>>> |        return {
>>> |            x:x,
>>> |            y:y,
>>> |            r: Math.sqrt(x*x+y*y),
>>> |            t: Math.atan(x,y)
>>> |        };
>>> |    }
>>>
>>> The arguments, however, could be any object, and those act totally
>>> normally. If an object is given as argument to the function that is an
>>> Object, the function can access the "real" Object.prototype by using
>>> Object.getPrototypeOf(...).
>>>
>>> |    window.newXHR = function newXHR(window) as serializable {
>>> |        return new this.XMLHttpRequest();
>>> |    }
>>> |
>>> |    var xhr = window.newXHR();
>>>
>>> However, it's also possible for the calling code not to give such
>>> information by passing only primitive values like string and numbers. I
>>> believe this is the most likely usage of this kind of function, at least
>>> from the web platform point of view.
>>>
>>>
>>>
>>> The good thing about those functions, is that they can safely be sent
>>> over the wires to another thread, or to another web page, because they do
>>> not possibly rely on any state or context.
>>>
>>> Formalizing those functions is also an important step towards enabling
>>> JS code to run safely deeper into the browser stack, by avoiding any
>>> possible use of objects that are not supposed to be interacted with at a
>>> given time (the calling code can control exactly what the called function
>>> has access to).
>>>
>>> A possible use case would be to defined arbitrary timing function for
>>> animations:
>>>
>>> |    function x2(x) as serializable { return x*x; }
>>> |
>>> |    // this is safe because SomeWebAnim knows he will call the function
>>>  only with numbers, so the code cannot access the DOM while it's still
>>> being computed, or because the DOM actually lives in another thread than
>>>  the animation code.
>>> |    SomeWebAnim.timingFunction = x2;
>>>
>>>
>>>
>>> Is there some interest from anyone else in formalizing this for a future
>>> version of EcmaScript? Or any comment?
>>> Francois
>>>
>>>
>>>
>>> PS: for the purposes of safety, we may want to disallow "eval" and
>>> "Function" inside this environment to make sure the code can be compiled
>>> ahead of time in all cases, and not force the usage of an interpreter. this
>>> could also be let to the choice of the author but be exposed as a slightly
>>> different concept (ie: compilable + serializable vs serializable only).
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>
>>
>>
>>  --
>>     Cheers,
>>     --MarkM
>>
>>
>> _______________________________________________
>> es-discuss mailing listes-discuss at mozilla.orghttps://mail.mozilla.org/listinfo/es-discuss
>>
>>
>> --
>> Peersm : http://www.peersm.com
>> node-Tor : https://www.github.com/Ayms/node-Tor
>> GitHub : https://www.github.com/Ayms
>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
> --
> Peersm : http://www.peersm.com
> node-Tor : https://www.github.com/Ayms/node-Tor
> GitHub : https://www.github.com/Ayms
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130926/3bcb0480/attachment-0001.html>


More information about the es-discuss mailing list