First one: simple (but incomplete) Fix
local NEW_G = {}
local rawgetfenv = getfenv
function getfenv(x)
local r = rawgetfenv(x)
if r == _G then
return NEW_G
end
return r
end
Note that this fix is incomplete.
os.run for example sets the environment of programs this way:
local f = loadstring(filecontents)
local env = setmetatable({}, {__index = _G})
setfenv(f, env)
So calling getfenv(1) in a program will return a table different from _G, but you can still get _G by doing "my_G = getmetatable(getfenv(1)).__index"
To fix this, you'd have to overwrite getmetatable.
(One may think you could also fix this by checking if getmetatable(r ).__index == _G in the getfenv function and then optionally doing getmetatable(r ).__index = NEW_G.
This doesn't work since you'd modify the environment of the function, not only of the return table)
Come to think of it, I think one could also exploit setfenv, getfenv, setmetatable & getmetatable to make code run in the host routine.
As I said, writing an unbreakable sandbox is hard
Fix 2 would be a bit more complicated, you'd have to write your own path parser.
Edited by ardera, 03 April 2018 - 04:37 PM.