[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Sandboxing
- From: Pierre-Yves Gérardy <pygy79@...>
- Date: Fri, 20 Jan 2012 11:30:37 +0100
Hello,
I have some questions regarding sandboxing in Lua 5.1.
Besides the functions tagged "SAFE" on the Wiki
(http://lua-users.org/wiki/SandBoxes), I would like to provide
sanitized versions of `get/setfenv`, `module`, `require` (no C libs),
and `load/dofile`.
The latter three are based on a safe, private `loadstring` version (no
bytecode, `setfenv(f,sandbox)`) and only have access to their own file
system root.
`require` and `module` work with `sandbox.package.loaded`, not the
global one a, and `sandbox.package.seeall` set `sandbox` as the index
of the module. The other package fields are not be exposed. (the code
is not shown here).
I also put guards around what get/setfenv can do, preventing _G and
its subfilelds to be get, and all functions whose environment are a _G
or a subfield to be the target of setfenv.
Am I covered?
```
local function each_in_tree (obj, fn, index,...)
index = index or {}
if index[obj] then return end
index[obj]=true
fn(obj,...)
if type(obj)=="table" then
for _,v in pairs( obj ) do
treemap(v,fn,index,...)
end
end
end
local forbidden_env={}
each_in_tree(_G, function(t)
if type (t) == "table" then
forbidden_env[t]=true
end
end )
--[[ A priori not needed
local forbidden_func={}
each_in_tree(_G, function(f)
if type(f)=="function" then
forbidden_func[f]=true
end
end )
--]]
local sandbox={
-- all safe fields
table = {
concat = table.concat,
...
}
}
local _getfenv = getfenv
local _setfenv = setfenv
local _loadstring = loadstring
local _G = _G
setfenv(1,sandbox)
function sandbox.getfenv (...)
local env = _getfenv(...)
if forbidden_env[env]
then return nil
else return env
end
end
function sandbox.setfenv (f,e)
if forbiddent_env[_getfenv(f)]
-- or forbidden_func[f] -- This should be covered by the above.
-- or forbiden_env[e] -- It should be impossible to get a forbidden
environment.
-- or f == 0 -- Safe too, I guess, since no dangerous env is available
then return 0
else return _setfenv(f,e)
end
end
-- based on the "even this is not safe "version of the Wiki
local function safe_loadstring (s,chunkname)
if s:match"^%.Lua" then
return false, "Attempt to load bytecode." -- are there other
bytecode signatures?
end
local f, message = _loadstring(s, chunkname)
if not f then
return f, message
end
_setfenv(f, sandbox)
return f
end
-- require and module implementations go here.
_setfenv(1,_G)
local f = loadfile"file"
setfenv(f,sandbox)
f()
```
-- Pierre-Yves