如何通过 C API 在自己的环境中执行不受信任的 Lua 文件

2024-05-16

我想通过调用在其自己的环境中执行不受信任的 .lua 文件lua_setfenv() http://pgl.yoyo.org/luai/i/lua_setfenv这样它就不会影响我的任何代码。

该函数的文档仅解释了如何调用函数,而不解释如何执行文件。

目前运行我使用的文件:

int error = luaL_loadfile(mState, path.c_str()) || lua_pcall(mState, 0, 0, 0);

我是否必须从 C API 调用“dofile”lua 函数lua_setfenv,或者有更优雅的方法吗?


请参阅 Lua User's Wiki 中的讨论沙箱 http://lua-users.org/wiki/SandBoxes,以及更一般的主题脚本安全 http://lua-users.org/wiki/ScriptSecurity。这类事情存在许多微妙和不那么微妙的问题。这是可以做到的,但要防止诸如for i=1,1e39 do end需要的不仅仅是限制沙箱可用的功能。

一般技术是为沙箱创建一个函数环境,其中包含允许的函数白名单。在某些情况下,该列表甚至可能为空,但让用户可以访问pairs()例如,几乎可以肯定是无害的。沙盒页面有一个按安全性细分的系统功能列表,可以作为构建此类白名单的方便参考。

然后你使用lua_setfenv()将函数环境应用于您加载(但尚未执行)的用户脚本lua_loadfile() or lua_loadstring()作为适当的。附加环境后,您可以使用以下命令执行它lua_pcall()和朋友。在执行之前,有些人实际上已经扫描了加载的字节码以查找他们不想允许的操作。这可用于绝对禁止循环或写入全局变量。

另一件需要注意的是,加载函数通常会加载预编译的字节码或 Lua 文本。事实证明,如果您从不允许预编译字节码,那么会安全得多,因为已经发现了许多导致虚拟机行为异常的方法,而这些方法都依赖于手工制作无效的字节码。由于字节码文件以明确定义的字节序列开始,该序列不是纯 ASCII 文本,因此您所需要做的就是将脚本读入字符串缓冲区,测试标记是否缺失,然后仅将其传递给lua_loadstring()如果它不是字节码。

会上进行了相当多的讨论Lua-L 邮件列表 http://www.lua.org/lua-l.html多年来这种事情一直存在,所以在那里搜索也可能会有所帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过 C API 在自己的环境中执行不受信任的 Lua 文件 的相关文章