So i'm trying to improve my sandbox a little bit at a time, and i think the first thing i need to fix is getfenv(). So, here's my "sandbox" so far:
function saferun(func)
setfenv(func,setmetatable({},{
__index = function(t,k)
if k == 'getfenv' then -- if getfenv is indexed, then...
return -- don't know yet
else
return getfenv()[k] -- if not, just return it from the old environment.
end
end
}))() -- run the function
end
saferun(function()
print(getfenv) -- > nil
end)
However, i don't want to just disable the ability to use getfenv, it's just so easy to bypass the sandbox with it. For example, if i said something like:
var = 'protected'
function saferun(func)
setfenv(func,setmetatable({},{
__index = function(t,k)
if k == 'var' then -- blocking "var" instead of getfenv
return 'blocked'
else
return getfenv()[k]
end
end
}))() -- run the function
end
saferun(function()
print(var) -- > "blocked"
-- But using getfenv, i can easily bypass the sandbox like this:
setfenv(1,getfenv(print))
print(var) -- > "protected"
end)
So, i know the problem is with getfenv, i just have no idea how i could attempt to modify it. I've tried a few ways, none in which where close to succeeding:
var = 'nope'
function saferun(func)
setfenv(func,setmetatable({},{
__index = function(t,k)
if k == 'getfenv' then
return function(f) -- returns this function instead of getfenv
local env = {}
for i,v in pairs (getfenv(f)) do
env[i]=v
end
return env
end
elseif k == 'var' then
return 'blocked'
else
return getfenv()[k]
end
end
}))() -- run the function
end
saferun(function()
setfenv(1,getfenv(print)) -- bypass
print(var) -- prints "nope" instead of "blocked".
end)
So if anyone has some insight on how it would be possible to modify getfenv, or maybe even another way of preventing this, i'd really appreciate it. Thanks.
