endojs / endo

Endo is a distributed secure JavaScript sandbox, based on SES
Apache License 2.0
829 stars 72 forks source link

How to use CommonJS modules in Compartment? #1788

Closed GulgDev closed 1 year ago

GulgDev commented 1 year ago

You can use import to run code as ESM. But is it possible to use require, module.exports and other CommonJS features in compartments? I don't think there's built-in support for this functions. Can I emulate their behaviour? And if I can, how do I do it?

kriskowal commented 1 year ago

As you have likely noticed, the Compartment API is very generic. The Compartment Mapper is one of many possible ways to bind compartments to specific module systems, specifically an approximation of Node.js that supports both CommonJS and ESM, in a style that is consistent with the needs of bundlers. The yet higher level @endo/bundle-source and @endo/import-bundle packages provide a specific zip-file based bundler that Agoric uses for contracts. The compartment mapper also has a bundle.js based on Compartment that is suitable for boot-strapping a script bundle (but not suitable for confinement). There are secure bundlers in the community based on Hardened JavaScript compartments: @naugtur can direct your attention to a LavaMoat plugin for WebPack that is suitable for confining third-party package on the web.

Mechanically, CommonJS requires the use of import hooks and virtual module sources. The Compartment API supports compiled ESM, using a module source constructor, nominally our @endo/static-module-record, and other language bindings with virtual module sources. JSON, CommonJS, and WebAssembly can all be accommodated with the virtual sources.

The @endo/cjs-module-analyzer is a fork of Guy Bedford’s version that is used by Node.js. The fork provides a heuristic static analysis of both the imports and export names of a CommonJS module that attempts to match the behavior of Node.js. The Node.js version does not do import analysis because the loader is synchronous. The compartment API is only async.