What i do know
So i know what a sandbox is. I know what it's used for, and how it can be useful in the right situation. I also know about a lot about function environments, tables, and metatables. Just a small overview on stuff i know to spare any explanation on.
The question
How can i make my sandbox attempt more secure? More specifically, how can i prevent it from being bypassed with the following code:
setfenv(1,setmetatable({},{ __index = function(t,k) if k == "workspace" then return nil else return getfenv()[k] end end })) print(workspace) -- > nil setfenv(1,getfenv(print)) -- bypassed, because i can set a new environment with the original one from print. print(workspace) -- > nil
The problem
So, i know what the problem is, but have no idea how to fix it. I could say any of the following to bypass this little sandbox:
setfenv(1,getfenv(print)) setfenv(1,getfenv(unpack)) setfenv(1,getfenv(script)) -- Or any other built-in global that the __index metamethod returns.
So, if anyone happens to have some insight on sandboxing, or even environments and metatables, i'd really appreciate some help. Thanks for reading.
Usually when you construct a sandbox, you don't define a blacklist. There are too many possibly out there that you aren't quite sure about. You define whitelist instead.
This is generally the strategy when it comes to sandboxing...
For example, this would be a sandboxed environment that only allows references to print...
local newEnvironment = { print = print } local metatable = { __metatable = "locked" -- Lock the global metatable } setmetatable(newEnvironment, metatable) setfenv(1, newEnvironment) print(1) --> 1 setfenv(1, { }) --> attempt to call global 'setfenv' (a nil value)