沙箱化插件执行
使用 setfenv/load 和自定义 _ENV 在受限环境中运行插件。
沙箱化插件执行 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
为什么要对插件使用沙箱?
不受信任的插件代码可能调用危险函数(os.execute、io.open、load),或访问应用程序的私有状态。沙箱可以限制代码能够执行的操作。
Lua 5.2+ 中的自定义 _ENV
在 Lua 5.2+ 中,每个代码块的全局环境都是 _ENV。使用受限的 _ENV 加载代码块,以限制其访问权限。
local function sandbox(code, env)
local chunk, err = load(code, "sandbox", "t", env)
if not chunk then return nil, err end
return pcall(chunk)
end构建安全环境
创建一个白名单环境,其中只包含安全的标准库函数。
local safeEnv = {
print = print,
type = type,
pairs = pairs,
ipairs = ipairs,
tostring = tostring,
tonumber = tonumber,
table = {insert=table.insert, concat=table.concat, sort=table.sort},
string = {format=string.format, find=string.find, match=string.match},
math = math,
}阻止危险函数
明确排除:os、io、load、loadfile、dofile、require、debug。不要将它们复制到 safeEnv 中。
在沙箱中加载文件
加载插件文件,并在沙箱环境中执行它。
local function sandboxFile(path, env)
local chunk, err = loadfile(path, "t", env)
if not chunk then return nil, err end
local ok, result = pcall(chunk)
if not ok then return nil, result end
return result
end提供 API 访问权限
只将安全的方法加入环境,为沙箱中的插件提供受限的应用程序 API 访问权限。
local pluginEnv = setmetatable({
app = {
on = function(e,f) app:on(e,f) end,
emit = function(e,...) app:emit(e,...) end,
log = function(msg) app:log(msg) end,
},
}, {__index = safeEnv})防止访问 _ENV
不要将 _G、_ENV 或 load 加入沙箱。这些内容可以让代码逃离受限环境。
使用 debug.sethook 进行指令计数
通过统计已执行的指令,并在达到限制后中止执行,来防止无限循环。
local function withLimit(fn, maxInstructions)
local count = 0
debug.sethook(function()
count = count + 1
if count > maxInstructions then
error("Instruction limit exceeded")
end
end, "", 100)
local ok, err = pcall(fn)
debug.sethook()
return ok, err
end内存限制
将指令计数与定期执行的 collectgarbage("count") 检查结合起来,在内存使用量超过阈值时中止执行。
捕获输出
将沙箱环境中的 print 替换为自定义函数,把输出捕获到缓冲区,而不是写入标准输出。
需要避免的沙箱逃逸方式
已知的逃逸途径包括:debug.getupvalue、对标准对象使用 getmetatable,以及对危险代码使用 coroutine.wrap。请仔细检查环境中的所有条目。
沙箱问题
如何防止沙箱中的代码调用 os.execute?
回顾:插件沙箱
创建只包含安全 API 的白名单 _ENV。使用 load(code, name, "t", safeEnv) 加载插件代码。使用指令计数来防止无限循环。切勿将 load、debug 或 _G 包含在沙箱中。
常见问题解答
「沙箱化插件执行」课时是免费的吗?
是的 — 「沙箱化插件执行」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「沙箱化插件执行」这节课中我会学到什么?
使用 setfenv/load 和自定义 _ENV 在受限环境中运行插件。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「沙箱化插件执行」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 发现和加载插件
- 插件 API 和钩子系统
- 沙箱化插件执行
- 版本管理和依赖管理