1

It appears that the official examples use a caja.js file that just wraps an iframe to load an URL from a server hosting a caja compilation service, which in turn, gets its input from some URL. The relevant API for that is available here.

However, what I really want is to just safely (and repeatedly) run a user-supplied piece of Javascript, like so:

for (var i = 0; i < N; ++i) {
    var x = getUserResult(currentState);
    updateState(currentState, x);
}

Is there any way to do this directly? The code here has the compiler. Why can't I just use that to compile the code and then run that within an emulated context? Is it because the only way to get a safe context in a browser is an iframe? And, if so, is there any way I can use an iframe to directly run given source code, without having to fetch it from an external URL?

Domi
  • 22,151
  • 15
  • 92
  • 122

1 Answers1

2

Caja needs an iframe no matter what. Both modes of execution require a set of JavaScript globals (obtained by creating the frame) which is available to be radically modified to enable safe execution.

Modern Caja (ES5 mode) does not require any server-side compilation step; provided the browser is compatible you can use Caja in the standard way and the server will never be contacted. To force this, specify es5Mode: true in the options to caja.initialize.

You can load guest code once and repeatedly execute it; just provide an api which lets the guest pass a function out when it's loaded, then call the function whenever you like.


For your use case, it would also be possible to use SES, the modern safe-eval subsystem of Caja, without using Caja itself at all; this would allow you to skip having any iframes, but would require you to write your code in a SES-compatible way; that is,

  • refraining from modifying global objects such as Object.prototype, and
  • protecting all objects directly or indirectly exposed to the user-supplied code using Object.freeze().)

If you're up for it, I do recommend using SES directly, as it removes a lot of indirections and total complexity, but it does require understanding the concepts to succeed at safety.

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
  • Great answer. One more question: Is there example code? Because the standard examples do not do it this way. – Domi Mar 21 '14 at 18:41
  • https://developers.google.com/caja/docs/callingguestcode/ is an example of a guest-written function being invoked by the host. – Kevin Reid Mar 21 '14 at 18:43
  • Sorry, I should have been more explicit. I meant an SES code example? The given examples only use iframe and guest code is always provided through a URL. – Domi Mar 21 '14 at 19:09
  • 1
    @Domi Good question. I don't know if there's really been any _example_ SES code written outside of Mark Miller's papers. I think that would be a good question to raise on [the mailing list](https://groups.google.com/forum/#!forum/google-caja-discuss) to see if anyone's memory is jogged, and if there isn't to start a discussion on what to write. – Kevin Reid Mar 21 '14 at 21:35
  • @Domi Die you habe any success on this? I would be interested in it also. – heinob Nov 02 '14 at 09:55
  • @heinob No, I had to ice that project for now. What I used was thread workers with whitelisting of "mostly safe functions", as explained [here](http://stackoverflow.com/questions/10653809/making-webworkers-a-safe-environment/). – Domi Nov 02 '14 at 10:21