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?
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.