Skip to content

Commit

Permalink
fix: allow some node modules to be imported in the sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Feb 21, 2019
1 parent 67d1e96 commit 45493aa
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 4 deletions.
18 changes: 15 additions & 3 deletions src/__tests__/module.test.js
Expand Up @@ -122,11 +122,23 @@ it('exports the path for non JS/JSON files', () => {
expect(mod.require('./sample-asset.png')).toBe('./sample-asset.png');
});

it('throws when requiring native node modules', () => {
it('returns module when requiring mocked builtin node modules', () => {
const mod = new Module(path.resolve(__dirname, '../__fixtures__/test.js'));

expect(() => mod.require('fs')).toThrow(
'Unable to import "fs". Importing Node builtins is not supported in the sandbox.'
expect(mod.require('path')).toBe(require('path'));
});

it('returns null when requiring empty builtin node modules', () => {
const mod = new Module(path.resolve(__dirname, '../__fixtures__/test.js'));

expect(mod.require('fs')).toBe(null);
});

it('throws when requiring unmocked builtin node modules', () => {
const mod = new Module(path.resolve(__dirname, '../__fixtures__/test.js'));

expect(() => mod.require('perf_hooks')).toThrow(
'Unable to import "perf_hooks". Importing Node builtins is not supported in the sandbox.'
);
});

Expand Down
52 changes: 51 additions & 1 deletion src/babel/module.js
Expand Up @@ -17,6 +17,44 @@ const vm = require('vm');
const fs = require('fs');
const path = require('path');

// Supported node builtins based on the modules polyfilled by webpack
// `true` means module is polyfilled, `false` means module is empty
const builtins = {
assert: true,
buffer: true,
child_process: false,
cluster: false,
console: true,
constants: true,
crypto: true,
dgram: false,
dns: false,
domain: true,
events: true,
fs: false,
http: true,
https: true,
module: false,
net: false,
os: true,
path: true,
punycode: true,
process: true,
querystring: true,
readline: false,
repl: false,
stream: true,
string_decoder: true,
sys: true,
timers: true,
tls: false,
tty: true,
url: true,
util: true,
vm: true,
zlib: true,
};

// Separate cache for evaled modules
let cache = {};

Expand Down Expand Up @@ -98,11 +136,23 @@ class Module {
}

require(id: string) {
if (id in builtins) {
// The module is in the allowed list of builtin node modules
// Ideally we should prevent importing them, but webpack polyfills some
// So we check for the list of polyfills to determine which ones to support
if (builtins[id]) {
/* $FlowFixMe */
return require(id);
}

return null;
}

// Resolve module id (and filename) relatively to parent module
const filename = this.resolve(id);

if (filename === id && !path.isAbsolute(id)) {
// Native Node modules
// The module is a builtin node modules, but not in the allowed list
throw new Error(
`Unable to import "${id}". Importing Node builtins is not supported in the sandbox.`
);
Expand Down

0 comments on commit 45493aa

Please sign in to comment.