Anti-pollution in ES5 by static verification (was: Addition of a global namespace function?)
On Fri, Dec 4, 2009 at 9:52 AM, Mark Miller <erights at gmail.com> wrote:
Given that primordials (other than the global object) are transitively frozen and that the above whitelist was adequately restrictive, each call of a closed function is fully isolated -- its connectivity to the world outside itself is fully under control of its caller. If the module-function's caller denies access to the global object, the indirect eval function, and to the Function constructor, then the module cannot pollute non-local state.
Note that Function.prototype.constructor should either not be on the whitelist (and should thereby be deleted), or it should be reassigned to something safe during the initial clean-or-die phase. Otherwise "(function(){}).constructor" would give access to the Function constructor, allowing global pollution after all.
I cannot currently find in the ES5 spec whether a conforming implementation may/must allow Function.prototype.constructor to be deleted or reassigned. Where in the spec is this dealt with?
2009/12/4 Mark Miller <erights at gmail.com>:
On Fri, Dec 4, 2009 at 9:52 AM, Mark Miller <erights at gmail.com> wrote:
Given that primordials (other than the global object) are transitively frozen and that the above whitelist was adequately restrictive, each call of a closed function is fully isolated -- its connectivity to the world outside itself is fully under control of its caller. If the module-function's caller denies access to the global object, the indirect eval function, and to the Function constructor, then the module cannot pollute non-local state.
Note that Function.prototype.constructor should either not be on the whitelist (and should thereby be deleted), or it should be reassigned to something safe during the initial clean-or-die phase. Otherwise "(function(){}).constructor" would give access to the Function constructor, allowing global pollution after all.
I cannot currently find in the ES5 spec whether a conforming implementation may/must allow Function.prototype.constructor to be deleted or reassigned. Where in the spec is this dealt with?
I think you have to allow all such properties to be deleted unless they have DontDelete.
Luckily it's not one of the magic undeletable properties in JSC and V8: bugs.webkit.org/show_bug.cgi?id=25527 (ignore misleading bug title).
Mark Miller wrote:
On Fri, Dec 4, 2009 at 9:52 AM, Mark Miller <erights at gmail.com> wrote:
Given that primordials (other than the global object) are transitively frozen and that the above whitelist was adequately restrictive, each call of a closed function is fully isolated -- its connectivity to the world outside itself is fully under control of its caller. If the module-function's caller denies access to the global object, the indirect eval function, and to the Function constructor, then the module cannot pollute non-local state.
Note that Function.prototype.constructor should either not be on the whitelist (and should thereby be deleted), or it should be reassigned to something safe during the initial clean-or-die phase. Otherwise "(function(){}).constructor" would give access to the Function constructor, allowing global pollution after all.
I cannot currently find in the ES5 spec whether a conforming implementation may/must allow Function.prototype.constructor to be deleted or reassigned.
It must.
Where in the spec is this dealt with?
Section 15,
In every case, the length property of a built-in Function object
described in this clause has the attributes [blah]. Every other
property described in this clause has the attributes
{ [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }
unless otherwise specified.
(was just looking it up :-)
On Fri, Dec 4, 2009 at 6:23 PM, David-Sarah Hopwood <david-sarah at jacaranda.org> wrote:
Mark Miller wrote:
On Fri, Dec 4, 2009 at 9:52 AM, Mark Miller <erights at gmail.com> wrote:
Given that primordials (other than the global object) are transitively frozen and that the above whitelist was adequately restrictive, each call of a closed function is fully isolated -- its connectivity to the world outside itself is fully under control of its caller. If the module-function's caller denies access to the global object, the indirect eval function, and to the Function constructor, then the module cannot pollute non-local state.
Note that Function.prototype.constructor should either not be on the whitelist (and should thereby be deleted), or it should be reassigned to something safe during the initial clean-or-die phase. Otherwise "(function(){}).constructor" would give access to the Function constructor, allowing global pollution after all.
I cannot currently find in the ES5 spec whether a conforming implementation may/must allow Function.prototype.constructor to be deleted or reassigned.
It must.
Where in the spec is this dealt with?
Section 15,
In every case, the length property of a built-in Function object
described in this clause has the attributes [blah]. Every other
property described in this clause has the attributes
{ [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }
unless otherwise specified.
(was just looking it up :-)
Great. That's what I was hoping for. Thanks.
Goal 5 for ES-Harmony at harmony:harmony, as agreed at
a previous EcmaScript meeting, is "Support a statically verifiable, object-capability secure subset.". At the time we agreed to that, we didn't know whether we'd be able to achieve it. Hypothesis: Regarding the formal properties of object-capabilities, practicalities aside, I think the above plan shows that it can be achieved on ES5-strict with a static verifier and a small clean-or-die startup script. An adequate hermetic eval can be defined by this startup script as
function hermeticEval(allegedClosedProgram) { return (1,eval)(verify(allegedClosedProgram)); }
Does this seem right?
[+commonjs] (And note subject change)
By "ES5 allows one to enumerate all properties on primordial objects except the global (window) object", I do not mean to imply that ES5 does not allow one to enumerate all properties of the global object. ES5 does allow this. I am only suggesting a procedure that does not do so.
[+commonjs] (And note subject change) By "ES5 allows one to enumerate all properties on primordial objects except the global (window) object", I do not mean to imply that ES5 does not allow one to enumerate all properties of the global object. ES5 does allow this. I am only suggesting a procedure that does not do so. On Fri, Dec 4, 2009 at 9:38 AM, Mark S. Miller <erights at google.com> wrote: > On Fri, Dec 4, 2009 at 8:41 AM, Alex Russell <alex at dojotoolkit.org> wrote: >> CommonJS modules don't solve the global pollution problem, because they can't. We're gonna keep blowing off limbs until we acknowledge that there's a design flaw in the language and take some positive action at a semantic level to correct it. > > ES5 allows one to enumerate all properties on primordial objects > except the global (window) object, to attempt to delete all properties > that are absent from a whitelist or die trying, and then to attempt > freeze all these cleaned up primordials (including all objects > reachable by traversal of remaining properties) or die trying. If both > of these succeed... > > ES5-strict enables to do a fully static scope analysis. Say one builds > a static verifier for Program text that does nothing but reject text > that either 1) is not a valid ES5-strict program unit, 2) has free > variables, or 3) uses a direct eval operator. A "closed function" is a > function that has no free variables. The natural rewrite of a module > is as the body of a closed function, perhaps packaged in a larger > closed expression or Program that would pass the above verifier. > Because ES5-strict is statically scoped, such a verifier effectively > removes the global object from the bottom of the scope chain of > Programs that pass this verifier. > > Given that primordials (other than the global object) are transitively > frozen and that the above whitelist was adequately restrictive, each > call of a closed function is fully isolated -- its connectivity to the > world outside itself is fully under control of its caller. If the > module-function's caller denies access to the global object, the > indirect eval function, and to the Function constructor, then the > module cannot pollute non-local state. > > -- > Cheers, > --MarkM > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -- Text by me above is hereby placed in the public domain Cheers, --MarkM