Can we have Function.isPure(f)
Irakli Gozalishvili wrote:
Hi,
I keep running into cases where I would like to know if function is pure. Although my interpretation of pure is not quite right but I don't know any better name. By pure in this context I would refer to functions that don't access an out scope variables and don't do any mutations of itself or it's properties no references to itself could be an option too. My intended use case for such a feature is to
IOW, 'stateless'; or 'serializable'. For in fact it means, that I can send f.toString() to the other side and when evaled, I can use it.
processes too, it would be great if we had something like Function.isPure(f). Also as far as I know jits already capture this info for optimisation purposes maybe it could be exposed ? Another alternative could be pure(function() { …. }) that would throw compile error if function followed is not pure.
Yes, it could be nice to have some API to help with this. Maybe not generic isPure or the like, maybe Function.serialize(f) and Function.deserialize(serialized_f) would be enough, the former returning null if not pure/stateless/serializable.
It is good to note that the function is serializable not only if it has no outer pointers, but also when its outer pointers only point to 'known primitives' (numbers, strings, null, true, false; not symbols).
I see security problems all over ... you own your function, you can make it "pure" or serializable ... you don't know your function, I believe there's no way you want that unknown function to be executed in your own sandbox opening doors for any sort of attack, i.e. ... this is pure, no outer scope access at all: function pure() { function(){return this}.call(null).Function.prototype.serialize = function() { /* boom */ } }
Le 05/11/2012 22:11, Andrea Giammarchi a écrit :
I see security problems all over ... you own your function, you can make it "pure" or serializable ... you don't know your function, I believe there's no way you want that unknown function to be executed in your own sandbox opening doors for any sort of attack, i.e. ... this is pure, no outer scope access at all: function pure() { function(){return this}.call(null).Function.prototype.serialize = function() { /* boom */ } }
Interesting. Assuming the own/don't own divide, there is a way to annotate (symbol/(Weak)Set) functions that are known pure and export only these.
I was doing that manually with Elsewhere but you have to know your code. I don't see a reasonable way to trust external one unless a mechanism to flag that unserialize as "not trusted" and keep that in mind per each function execution ( something like dealing with images in canvas then try to access/modify them which results in security exception if image is not trusted ) ... Elsewhere, 2009, if anyone is interested: webreflection.blogspot.com/2009/07/elsewhere-sandboxes-have-never-been.html
On Mon, Nov 5, 2012 at 11:52 AM, Irakli Gozalishvili <rfobic at gmail.com>wrote:
Hi,
I keep running into cases where I would like to know if function is pure. Although my interpretation of pure is not quite right but I don't know any better name. By pure in this context I would refer to functions that don't access an out scope variables and don't do any mutations of itself or it's properties no references to itself could be an option too. My intended use case for such a feature is to allow transfer (by which I meant just coping) of such functions across workers / processes. For example in Mozilla add-on we have a context-menu API addons.mozilla.org/en-US/developers/docs/sdk/latest/packages/addon-kit/context-menu.html which has limited declarative syntax for context definitions where specific context item should appear. There is also programable API through content-script files where one could write a predicate function that is invoked in the page scope with a node reference on which event has occurred. In most though pure function would have being enough but there is no way for us to know weather given function refers to outer scope variables. Same use cases arise with web workers and node processes too, it would be great if we had something like Function.isPure(f). Also as far as I know jits already capture this info for optimisation purposes maybe it could be exposed ? Another alternative could be pure(function() { …. }) that would throw compile error if function followed is not pure.
Hi Irakli, because of < harmony:function_to_string>, you can
now code this yourself in JS, but only by writing a full JS parser and scope analyzer. Alternatively, you can use SES < code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses>,
which evaluates the function in a scope preventing it from accessing any non-whitelisted external variables, without needing to parse it, and therefore without needing to determine whether it actually does so.
We use this ability to safely copy closed functions at strawman:concurrency#vats (last paragraph) and starting at strawman:concurrency#vat.evallater_as_async
I think "closed strict function" is adequate for these purposes. By "closed" though, we need only mean "except for the whitelisted globals", using the whitelist at < code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/whitelist.js>
as updated for ES6.
On Mon, Nov 5, 2012 at 1:11 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
I see security problems all over ... you own your function, you can make it "pure" or serializable ... you don't know your function, I believe there's no way you want that unknown function to be executed in your own sandbox opening doors for any sort of attack, i.e. ... this is pure, no outer scope access at all: function pure() { function(){return this}.call(null).Function.prototype.serialize = function() { /* boom */ } }
JavaScript is singly threaded. Within a given JavaScript thread/process/worker/vat/whatever, any code which is ever given control can just go into an infinite loop or throw, so none of the within-vat sandboxes attempt to make any claims about availability[1]. However, SES, by following the object-capability model, makes strong claims about integrity. Irakli's notion of closed strict functions is adequate for safe remote execution, where "safe" means that it can cause no effects on the integrity of its importing context not explicitly authorized by the references passed into it.
[1] MS WebSandbox claimed only resistance to availability accident, not to availability attack.
not sure I follow the single thread part which I believe isn't bringing anything new here or maybe I have missed the point.
What I am saying is that only via that SES "thing", or similar parsers, you might add security but I wonder if the Function, as far as I can tell being allowed, is able to create runtime potential problems after SES resulting in opened doors for attacks.
Anyway, if performance is not an issue then yes, such parser with whitelist is the least someone should think about but I don't see that natively implemented, also because everyone would like to be able to add own namespace in the list and I believe making a white list modifiable from anyone is again a security problem.
On Mon, Nov 5, 2012 at 2:22 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
not sure I follow the single thread part which I believe isn't bringing anything new here or maybe I have missed the point.
My point was only that, in SES, the attack you showed is only an attack on availability, and so a non-issue.
What I am saying is that only via that SES "thing", or similar parsers,
SES gets its security without needing to do a full parse. That's part of why it's cheap and reliable.
you might add security but I wonder if the Function, as far as I can tell being allowed, is able to create runtime potential problems after SES resulting in opened doors for attacks.
SES replaces the Function constructor with a safe alternative code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#733
Anyway, if performance is not an issue then yes, such parser with whitelist is the least someone should think about but I don't see that natively implemented,
SES doesn't need to do a full parse.
also because everyone would like to be able to add own namespace in the list and I believe making a white list modifiable from anyone is again a security problem.
Making the whitelist modifiable would be fatal. I don't understand your point.
On Mon, Nov 5, 2012 at 2:22 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
not sure I follow the single thread part which I believe isn't bringing anything new here or maybe I have missed the point.
What I am saying is that only via that SES "thing", or similar parsers, you might add security but I wonder if the Function, as far as I can tell being allowed, is able to create runtime potential problems after SES resulting in opened doors for attacks.
Anyway, if performance is not an issue then yes, such parser
code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/atLeastFreeVarNames.js is what SES needs to do instead of parsing.
my point on namespaces was this one: everyone want's to use jQuery, then underscore, then this or that ... then you need to be able to modify the white list.
that wants ...
On Mon, Nov 5, 2012 at 2:35 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
my point on namespaces was this one: everyone want's to use jQuery, then underscore, then this or that ... then you need to be able to modify the white list.
Thanks for the clarification. jQuery and much else runs fine under SES, but requires more mechanism than a simple rejection of code that refers to global variables outside the whitelist. The basic confining-eval construct in the current SES implementation is currently called cajaVM.compileExpr:
code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/startSES.js#617
cajaVM.compileExpr(src)(envObject)
will redirect all apparently global variable references in src into property accesses on envObject. Yes, internally we use a "with" to implement that, though other tricks are possible.
The only reason this is currently on "cajaVM" is that we're not yet ready to propose a std SES API, since the current one is based only on ES5. In std SES, this API would be provided by an ES6 module.
I keep running into cases where I would like to know if function is pure. Although my interpretation of pure is not quite right but I don't know any better name. By pure in this context I would refer to functions that don't access an out scope variables and don't do any mutations of itself or it's properties no references to itself could be an option too. My intended use case for such a feature is to allow transfer (by which I meant just coping) of such functions across workers / processes. For example in Mozilla add-on
we have a context-menu API addons.mozilla.org/en-US/developers/docs/sdk/latest/packages/addon-kit/context-menu.html which has limited declarative syntax for context definitions where specific context item should appear. There is also programable API through content-script files where one could write a predicate function that is invoked in the page scope with a node reference on which event has occurred. In most though pure function would have being enough but there is no way for us to know weather given function refers to outer scope variables. Same use cases arise with web workers and node processes too, it would be great if we had something like Function.isPure(f). Also as far as I know jits already capture this info for optimisation purposes maybe it could be exposed ? Another alternative could be pure(function() { …. }) that would throw compile error if function followed is not pure.
Thanks!
Irakli Gozalishvili Web: www.jeditoolkit.com