-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
Description
The timeout property on many of the vm module's functions isn't completely foolproof. In the following example, some sandboxed code executed by vm.runInNewContext with a timeout of 5ms schedules an infinite loop to run after a promise resolves, and then synchronously executes an infinite loop. The synchronous infinite loop is killed by the timeout, but then the sch 6A4C eduled loop fires and never ends.
vm.runInNewContext(
'Promise.resolve().then(()=>{while(1)console.log("foo", Date.now());}); while(1)console.log(Date.now())',
{console:{log(){console.log.apply(console,arguments);}}},
{timeout:5}
);Some output:
1442966735705
...
1442966735710
1442966735710
1442966735710
1442966735710
1442966735710
Error: Script execution timed out.
at Error (native)
at ContextifyScript.Script.runInNewContext (vm.js:18:15)
at Object.exports.runInNewContext (vm.js:49:17)
at repl:1:4
at REPLServer.defaultEval (repl.js:164:27)
at bound (domain.js:250:14)
at REPLServer.runBound [as eval] (domain.js:263:12)
at REPLServer.<anonymous> (repl.js:392:12)
at emitOne (events.js:82:20)
at REPLServer.emit (events.js:169:7)
> foo 1442966735715
foo 1442966735716
foo 1442966735716
foo 1442966735716
foo 1442966735716
... [continues forever]
I'm not really sure what a good solution for this would be, if it's possible, and whether the vm module intends to stand up to this sort of thing. At the very least I think vm's docs should have a note that the timeout property works by best-effort or something and isn't completely foolproof, so no one thinks it's safe to try to use it to sandbox user code in a guaranteed timely manner.