0

In Mozilla's JavaScript environment, it is possible to load other script from a URL using the loadSubScript() method of the mozIJSSubScriptLoader interface.

It is possible to specify an object used as the scope object for the script being executed. However, as explained in this Stackoverflow answer, "undeclared variables will still be created in the outer scope and the outer scope will be searched for variables that cannot be resolved in the subscript scope."

This answer recommends to use Components.utils.Sandbox as an alternative.

However, this mechanism apparently enables security restrictions. For Mozilla bug 876089, I tried out simply replacing the regular JS object with a sandbox. The loaded script could then no longer use Components.utils, placed in the scope object as "Cu":

EXCEPTION: Permission denied for to call method UnnamedClass.import

Now the question: In the Mozilla environment, how can I best load scripts in a way that just prevents leaking of symbols via the caller's global object, but still allows it to use all the symbols explicitly placed in the scope object without imposing any security restrictions?

Community
  • 1
  • 1
Jens Müller
  • 302
  • 4
  • 13

1 Answers1

1

Indeed, using a Sandbox is the right approach. Security settings can be managed by using a special principal as the scope object, instead of a plain JavaScript object.

By using the system principal, all security checks are disabled.

The code then looks like this:

Components.utils.import("resource://gre/modules/Services.jsm");
var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
var scopeObject = new Components.utils.Sandbox(systemPrincipal); 
// set properties of the scope object like this:
// scopeObject.someProperty = someValue;
var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
  .getService(Components.interfaces.mozIJSSubScriptLoader);
// Set uri to the uri of the script to load
loader.loadSubScript(uri, module, "UTF-8");
Jens Müller
  • 302
  • 4
  • 13