Skip to content

Commit ca512b7

Browse files
committed
Run notebooks inside a Node sandbox (vm module)
it's still not safe at this point, **process** should be removed from the sandbox
1 parent 4ffac95 commit ca512b7

File tree

3 files changed

+32
-6
lines changed

3 files changed

+32
-6
lines changed

bin/bin.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
*/
2222

2323
import { fork, isMaster } from "cluster";
24+
import { readFileSync } from "fs";
2425
import * as opn from "opn";
26+
import { TextDecoder } from "util";
27+
import * as vm from "vm";
2528
import * as WebSocket from "ws";
29+
import { ClusterRPC } from "../src/rpc";
2630
import { createHTTPServer } from "./server";
2731

2832
// Constants
@@ -71,5 +75,27 @@ if (isMaster) {
7175
});
7276
} else {
7377
console.log("[%s] Worker started.", process.pid);
74-
require("../src/sandbox.ts");
78+
const sandboxCode = readFileSync("../build/website/sandbox.js").toString();
79+
const clusterRPC = new ClusterRPC(process);
80+
// TODO We should not let user to have access to `process`.
81+
// const binding = process.binding('fs');
82+
// binding
83+
const sandbox = {
84+
Buffer,
85+
TextDecoder,
86+
clusterRPC,
87+
process,
88+
require: safeRequire
89+
};
90+
vm.createContext(sandbox);
91+
vm.runInContext(sandboxCode, sandbox);
92+
}
93+
94+
function safeRequire(moduleName) {
95+
const allowedModules = ["url", "http", "https"];
96+
if (allowedModules.indexOf(moduleName) < 0) {
97+
console.log(moduleName);
98+
throw new Error("Calling require is forbidden.");
99+
}
100+
return require(moduleName);
75101
}

src/rpc.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export class WebSocketRPC extends RPCBase {
215215
}
216216

217217
export class ClusterRPC extends RPCBase {
218-
constructor(private process, private calledFromMaster = false) {
218+
constructor(private process) {
219219
super();
220220
}
221221

@@ -229,9 +229,7 @@ export class ClusterRPC extends RPCBase {
229229

230230
start(handlers: RpcHandlers): void {
231231
super.start(handlers);
232-
if (!this.calledFromMaster) {
233-
this.process.on("message", this.receive);
234-
}
232+
this.process.on("message", this.receive);
235233
}
236234

237235
stop(): void {

src/sandbox.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import { ClusterRPC, RPC, WindowRPC } from "./rpc";
2323
import { describe, InspectorData, InspectorOptions } from "./serializer";
2424
import { global, globalEval, IS_WEB, URL } from "./util";
2525

26+
declare const clusterRPC: ClusterRPC;
27+
2628
async function fetchText(url: string) {
2729
const ab = await fetchArrayBuffer(url);
2830
const enc = new TextDecoder();
@@ -84,7 +86,7 @@ const rpc = function(): RPC {
8486
.getAttribute("content");
8587
return new WindowRPC(window.parent, channelId);
8688
}
87-
return new ClusterRPC(process);
89+
return clusterRPC;
8890
}();
8991
rpc.start({ runCell });
9092

0 commit comments

Comments
 (0)