On Mon, Dec 7, 2009 at 7:37 AM, Bluebie <
bl...@creativepony.com> wrote:
>
> Node's implementation of the 'secure modules' common-js specification
> is syntax compatible, but is not actually factually secure. Modules
> loaded can infect the global namespace with all sorts of junk.
> Regardless, it is an event loop, and you get just one per node
> process, so if you run multiple apps in one node instance, one badly
> coded app could adversely affect the performance of the rest.
> Additionally, many computer systems now days contain multiple cores or
> CPU's, and the event loop runs on just one of them, so you may be able
> to get a lot more performance out of your system when using multiple
> processes.
>
In fact, nothing in the Commonjs securable modules specification
asserts that an implementation should secure the modules in unique
execution contexts. The only mention of sandboxing is related to the
module search path attribute (it may not be sandboxed). Security of
context is implied by the spec's opening description:
"These modules are offered privacy of their top scope, facility for
importing singleton objects from other modules, and exporting their
own API." (
http://wiki.commonjs.org/wiki/Modules/1.1)
However, it is not asserted by the contract of the specification,
IIRC. I'll try to figure out why this omission occurred; perhaps it
was for reasons of compatibility.
I've been toying around with the idea of context-isolated modules in
the browser. They have the advantage of being conceptually easy to
manage in terms of code isolation. They can be used to securely
modularize foreign javascript code without code-level modification or
the addition of boilerplate to that code. Unfortunately, they have
the disadvantage of breaking potentially important type inference
features (see below). My tests have been in the browser, using
iframes to provide 'clean' window elements as an execution context for
potentially invasive code. I am following the work of Dean Edwards:
http://dean.edwards.name/weblog/2006/11/hooray/ and Andrea Giammarchi:
http://webreflection.blogspot.com/2009/07/elsewhere-sandboxes-have-never-been.html,
and attempting to link it to James Burke's run.js asynchronous
javascript loader
http://code.google.com/p/runjs/.
This same pattern could be adapted to node. v8 uses contexts to
provide code isolation and caching of these contexts to eliminate the
performance bottleneck incurred by generating the contexts. See
http://code.google.com/apis/v8/embed.html#contexts.
If the proper hooks were provided, applications written in node could
select to use context isolation for each request. Is this something
that could be useful? I can see that it would also be limiting to
enforce and would prefer that it not become standard.
Above I alluded to frustrations about the breakage of introspective
capabilities: In other languages you often can't modify primordial
objects at runtime, so they skirt some of the fundamental issues that
arise from using multiple execution contexts in the same environment.
In javascript, what happens when you compare references from two
distinct contexts can be quite frustrating e.g.:
(new context1.Array()) instanceof context2.array
will invariably be false. The primordial objects from which each
array is descended are not the same. This behavior is technically
correct, but I can imagine it being frustrating to deal with. More
frustratingly, this issue crosses javascript's fuzzy border between
dynamic and static. In a fully dynamic language with multiple
contexts and the ability to share references between them it would be
possible to dynamically subclass the primordials of the 'global' top
level scope and resolve this issue, but it is simply not possible to
modify the prototype chains of primordials in this way (at least in
the browser context I have tested). Perhaps this is not true in v8, I
am not sure.
Erik