Re: [nodejs] Compiling JS for Safe vm.runInNewContext()

101 views
Skip to first unread message

Mark S. Miller

unread,
Jul 11, 2012, 3:05:07 PM7/11/12
to nod...@googlegroups.com, Google Caja Discuss
[+google-caja-discuss]

On Wed, Jul 11, 2012 at 11:24 AM, Kevin O <kevino...@gmail.com> wrote:
Thanks for the suggestion. Caja does seem like it's pretty robust but maybe more than I need. Plus, I would have to call out to a service every time I compile or re-implement the whole thing in node to use it. Neither is really an option, unfortunately.

On Wednesday, 11 July 2012 13:17:23 UTC-4, Marcel wrote:
Look at Google Caja, this does exactly what you describe. It's a very complicated problem.


Caja as a whole secures JS, html, css, and the browser/dom API. On Node, the only relevant component is the securing of JS.

Caja has two ways to secure JS. 

  * For pre-ES5 systems, Caja uses a server-side translator to translate from the secure subset of ES5 to ES3. This is the "very complicated" that Marcel refers to.

  * For ES5 compliant systems, Caja uses a simple client-side translation-free system, the SES (Secure EcmaScript) library[1], to enforce that further code in that evaled in that context is limited to the object-capability subset of ES5.

Mark S. Miller

unread,
Jul 11, 2012, 3:08:03 PM7/11/12
to nod...@googlegroups.com, Google Caja Discuss
On Wed, Jul 11, 2012 at 12:05 PM, Mark S. Miller <eri...@google.com> wrote:
[+google-caja-discuss]

On Wed, Jul 11, 2012 at 11:24 AM, Kevin O <kevino...@gmail.com> wrote:

Thanks for the suggestion. Caja does seem like it's pretty robust but maybe more than I need. Plus, I would have to call out to a service every time I compile or re-implement the whole thing in node to use it. Neither is really an option, unfortunately.

On Wednesday, 11 July 2012 13:17:23 UTC-4, Marcel wrote:
Look at Google Caja, this does exactly what you describe. It's a very complicated problem.


Caja as a whole secures JS, html, css, and the browser/dom API. On Node, the only relevant component is the securing of JS.

Caja has two ways to secure JS. 

  * For pre-ES5 systems, Caja uses a server-side translator to translate from the secure subset of ES5 to ES3. This is the "very complicated" that Marcel refers to.

  * For ES5 compliant systems, Caja uses a simple client-side translation-free system, the SES (Secure EcmaScript) library[1], to enforce that further code in that evaled in that context is limited to the object-capability subset of ES5.

Forgot the punch line: Node is based on modern v8, and so is ES5 compliant. SES on Node should work fine.




--
    Cheers,
    --MarkM

๏̯͡๏ Jasvir Nagra

unread,
Jul 11, 2012, 3:20:00 PM7/11/12
to google-ca...@googlegroups.com, kevino...@gmail.com, nod...@googlegroups.com
Hi Kevin,

Specifically if you know you're in a ES5-strict mode compliant js engine, like a modern V8 to use this, load caja.js and initialize caja as follows:

caja.initialize({ forceES5Mode: true });
caja.load(undefined /* if you don't need a dom */, caja.policy.net.ALL /* your url policy */, function (frame) {
  frame.code('a base url', 'text/javascript', '...your js code')
          .run();
});

To expose more apis to this isolated code, please see https://developers.google.com/caja/

jas



On Wed, Jul 11, 2012 at 12:05 PM, Mark S. Miller <eri...@google.com> wrote:

felix

unread,
Jul 11, 2012, 3:29:02 PM7/11/12
to google-ca...@googlegroups.com, nod...@googlegroups.com
I'll look at adding the SES js files to the CDN at the next version push, which will be either next week or the week after.

On Wed, Jul 11, 2012 at 12:05 PM, Mark S. Miller <eri...@google.com> wrote:

๏̯͡๏ Jasvir Nagra

unread,
Jul 11, 2012, 3:35:51 PM7/11/12
to google-ca...@googlegroups.com, nod...@googlegroups.com
This should already be up on ssl.gstatic.com.

Tristan Slominski

unread,
Oct 8, 2012, 5:09:59 PM10/8/12
to google-ca...@googlegroups.com
Hey Mark, 

Do you have more guidance on how to bootstrap SES in Node.js? I've tried requiring the initSES file (as a module), but it' keeps on not finding "Function" for some reason. 

> var ses = require('./initSES-minified.js');
TypeError: Cannot read property 'prototype' of undefined
    at repairES5Module (./initSES-minified.js:137:265)
    at Object.<anonymous> (./initSES-minified.js:241:729)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at repl:1:11
    at REPLServer.self.eval (repl.js:111:21)
> var ses = require('./initSES.js');
TypeError: Cannot read property 'prototype' of undefined
    at repairES5Module (./initSES.js:1980:22)
    at Object.<anonymous> (./initSES.js:3309:3)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at repl:1:11
    at REPLServer.self.eval (repl.js:111:21)
> var ses = require('./initSESPlus.js');
TypeError: Cannot read property 'prototype' of undefined
    at repairES5Module (./initSESPlus.js:1981:22)
    at Object.<anonymous> (./initSESPlus.js:3310:3)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at repl:1:11
    at REPLServer.self.eval (repl.js:111:21)

Also, I've found it difficult to follow the examples because they're very browser centric. For example, the caja.js stuff breaks for lack of "window" and such.

Given that I have the following in Node.js:

var script = "console.log('hi');";
var vm = require( 'vm' );

var sandbox = { console : Object.freeze( console ) };
vm.runInContext( script, vm.createContext( Object.freeze( sandbox ) ) );
// # -> prints "hi"

How do I get SES in there? I'm assuming I should do something like:

cajaVM.eval( "vm.runInContext( script, vm.createContext( Object.freeze( sandbox ) ) );" );

๏̯͡๏ Jasvir Nagra

unread,
Oct 18, 2012, 4:58:25 PM10/18/12
to Google Caja Discuss, Kris Kowal, Mark Miller
hi Tristan,

We haven't tried running cajajs on node (as you point out, we're currently geared up to be very browser specific) but we can try to help you debug this since it means getting caja up and running on node.  I looked into this briefly and it appears that declaring a var in node creates a new variable even if one exists in scope.

Here's a small test case showing the issue:

jasvir-macbookpro:ses jasvir$ cat test.js 
var Function;
var x = Function.prototype.call;
jasvir-macbookpro:ses jasvir$ node
> require('./test.js')
TypeError: Cannot read property 'prototype' of undefined
    at Object.<anonymous> (/Users/jasvir/src/svn-changes/caja-uploads-to-maven-CLEAN/google-caja/ant-lib/com/google/caja/ses/test.js:2:17)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at repl:1:2
    at REPLServer.self.eval (repl.js:111:21)
    at Interface.<anonymous> (repl.js:250:12)

Is this expected semantics of node?  If so, removing the var decls for Function, RegExp etc will help you make progress.
Reply all
Reply to author
Forward
0 new messages