secure-require
Advanced tools
Comparing version
/// <reference types="node" /> | ||
import * as vm from 'vm'; | ||
export default function secureRequire(this: any, specifier: string, permittedModules?: Array<string>, context?: vm.Context): Object | undefined; | ||
import vm from 'vm'; | ||
export default function secureRequire(this: any, specifier: string, permittedModules?: string[], context?: vm.Context, cache?: { | ||
[index: string]: any; | ||
}): Object | undefined; |
"use strict"; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var fs = __importStar(require("fs")); | ||
var mod = require('module'); // Reasons:tm: | ||
var path = __importStar(require("path")); | ||
var vm = __importStar(require("vm")); | ||
function secureRequire(specifier, permittedModules, context) { | ||
var fs_1 = __importDefault(require("fs")); | ||
var Module = require('module'); // Reasons:tm: | ||
var path_1 = __importDefault(require("path")); | ||
var vm_1 = __importDefault(require("vm")); | ||
function secureRequire(specifier, permittedModules, context, cache) { | ||
if (!specifier || specifier === '') | ||
throw new Error(); | ||
if (!context || !vm.isContext(context)) | ||
context = vm.createContext(); | ||
if (!context || !vm_1.default.isContext(context)) | ||
context = vm_1.default.createContext(); | ||
if (!permittedModules || !Array.isArray(permittedModules)) | ||
permittedModules = mod.builtinModules; | ||
permittedModules = Module.builtinModules; | ||
cache = cache || Object.create(null); | ||
// If a NativeModule is required, not much can be done. | ||
@@ -30,10 +27,26 @@ // TODO: Talk to people about exposing the NativeModule class so that these | ||
// module = module.parent | ||
var filename = mod.Module._resolveFilename(specifier, module, false); | ||
var newModule = new mod.Module(filename, module); | ||
var dirname = path.dirname(filename); | ||
var src = fs.readFileSync(filename, 'utf8'); | ||
var fn = vm.compileFunction(src, ['exports', 'require', 'module', '__filename', '__dirname'], { filename: filename, parsingContext: context }); | ||
fn.call(newModule.exports, newModule.exports, function (id) { return secureRequire(id, permittedModules, context); }, newModule, filename, dirname); | ||
var filename = Module._resolveFilename(specifier, module, false); | ||
var cached = cache[filename]; | ||
if (cached) { | ||
return cached.exports; | ||
} | ||
var newModule = new Module(filename, module); | ||
cache[filename] = newModule; | ||
var threw = true; | ||
try { | ||
secureLoad(newModule, filename, context, permittedModules, cache); | ||
threw = false; | ||
} | ||
finally { | ||
if (threw) | ||
delete cache[filename]; | ||
} | ||
return newModule.exports; | ||
} | ||
exports.default = secureRequire; | ||
function secureLoad(newModule, filename, context, permittedModules, cache) { | ||
var dirname = path_1.default.dirname(filename); | ||
var src = fs_1.default.readFileSync(filename, 'utf8'); | ||
var compiled = vm_1.default.compileFunction(src, ['exports', 'require', 'module', '__filename', '__dirname'], { filename: filename, parsingContext: context }); | ||
compiled.call(newModule.exports, newModule.exports, function (id) { return secureRequire(id, permittedModules, context, cache); }, newModule, filename, dirname); | ||
} |
{ | ||
"name": "secure-require", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "A secure require implementation for ECMAScript", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -8,11 +8,18 @@ # secure-require | ||
APIs. This allows you to make sure that none of the sub-dependencies try | ||
anything unexpected, no matter which version you upgrade to. | ||
anything unexpected, or are able to alter the global objects of your own application | ||
code, no matter which version you upgrade to. | ||
## Security Model | ||
* Full global isolation: Each top-level dependency is run in a separate container. | ||
* Safely restrict the `require` tree to only a subset of allowed modules, including restricting Node.js core access. | ||
## Features | ||
1. Run each top-level dependency in a separate container. | ||
2. Restrict each dependency to `require` only a subset of core modules. | ||
3. Zero dependencies (duh). | ||
1. Zero dependencies (duh). | ||
2. Uses the same stuff `require` uses behind-the-scenes, so performance dip should be next to none. | ||
3. Supports core, third party and local modules. | ||
4. Cache modules in the same context so that you get *close* to the speed of the original `require` function without losing any of the security guarantees. | ||
### Installation | ||
## Installation | ||
@@ -23,3 +30,3 @@ ``` | ||
### Usage | ||
## Usage | ||
@@ -39,4 +46,4 @@ ```js | ||
### License | ||
## License | ||
[MIT](./LICENSE) |
11817
8.15%123
13.89%47
17.5%