所以Lua似乎是在我的应用程序中实现安全"用户脚本"的理想选择.
但是,嵌入lua的大多数示例似乎都包括加载所有标准库,包括"io"和"package".
所以我可以从我的解释器中排除这些库,但即使是基本库也包含访问文件系统的函数"dofile"和"loadfile".
如何删除/阻止这些不安全的函数,而不仅仅是一个甚至没有像"ipairs"函数这样的基本内容的解释器?
Kar*_*and 53
您可以通过setfenv()设置运行不受信任代码的功能环境.这是一个大纲:
local env = {ipairs}
setfenv(user_script, env)
pcall(user_script)
Run Code Online (Sandbox Code Playgroud)
该user_script功能只能访问其环境中的内容.因此,您可以显式添加您希望不受信任的代码可以访问的功能(白名单).在这种情况下,用户脚本只能访问ipairs,但没有别的(dofile,loadfile,等).
有关lua沙盒的详细信息,请参阅Lua Sandboxes.
BMi*_*tch 33
这是Lua 5.2的解决方案(包括也适用于5.1的示例环境):
-- save a pointer to globals that would be unreachable in sandbox
local e=_ENV
-- sample sandbox environment
sandbox_env = {
ipairs = ipairs,
next = next,
pairs = pairs,
pcall = pcall,
tonumber = tonumber,
tostring = tostring,
type = type,
unpack = unpack,
coroutine = { create = coroutine.create, resume = coroutine.resume,
running = coroutine.running, status = coroutine.status,
wrap = coroutine.wrap },
string = { byte = string.byte, char = string.char, find = string.find,
format = string.format, gmatch = string.gmatch, gsub = string.gsub,
len = string.len, lower = string.lower, match = string.match,
rep = string.rep, reverse = string.reverse, sub = string.sub,
upper = string.upper },
table = { insert = table.insert, maxn = table.maxn, remove = table.remove,
sort = table.sort },
math = { abs = math.abs, acos = math.acos, asin = math.asin,
atan = math.atan, atan2 = math.atan2, ceil = math.ceil, cos = math.cos,
cosh = math.cosh, deg = math.deg, exp = math.exp, floor = math.floor,
fmod = math.fmod, frexp = math.frexp, huge = math.huge,
ldexp = math.ldexp, log = math.log, log10 = math.log10, max = math.max,
min = math.min, modf = math.modf, pi = math.pi, pow = math.pow,
rad = math.rad, random = math.random, sin = math.sin, sinh = math.sinh,
sqrt = math.sqrt, tan = math.tan, tanh = math.tanh },
os = { clock = os.clock, difftime = os.difftime, time = os.time },
}
function run_sandbox(sb_env, sb_func, ...)
local sb_orig_env=_ENV
if (not sb_func) then return nil end
_ENV=sb_env
local sb_ret={e.pcall(sb_func, ...)}
_ENV=sb_orig_env
return e.table.unpack(sb_ret)
end
Run Code Online (Sandbox Code Playgroud)
然后使用它,你会my_func像下面这样调用你的函数():
pcall_rc, result_or_err_msg = run_sandbox(sandbox_env, my_func, arg1, arg2)
Run Code Online (Sandbox Code Playgroud)
清除不良情况的最简单方法之一是首先加载您自己设计的Lua脚本,该脚本执行以下操作:
load = nil
loadfile = nil
dofile = nil
Run Code Online (Sandbox Code Playgroud)
或者,您可以setfenv用来创建一个受限的环境,可以在其中插入特定的安全功能。
完全安全的沙箱有点难。如果您从任何地方加载代码,请注意,预编译的代码可能会使Lua崩溃。如果没有关闭系统,甚至完全受限制的代码也可能陷入无限循环并无限期地阻塞。
您可以使用lua_setglobalLua API 提供的函数在全局命名空间中设置这些值,这nil将有效防止任何用户脚本能够访问它们。
lua_pushnil(state_pointer);
lua_setglobal(state_pointer, "io");
lua_pushnil(state_pointer);
lua_setglobal(state_pointer, "loadfile");
...etc...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24645 次 |
| 最近记录: |