如何在Lua中封装IO函数以防止用户离开X目录
2013-12-21 13:51:37
收藏:0
阅读:133
评论:2
你怎样在 Lua 中包装 IO(输入/输出)函数来防止有人离开顶级目录?
你将它们放置在"MyDoc"目录中,它们可以完全访问MyDoc子目录中的所有内容,但不能例如回到C驱动器或其他任何地方。
点赞
用户869951
假设你将用户环境设置为沙箱,所以他们不能使用内置的“require”、“dofile”或“setatable”函数?
基本上,你必须限制他们能够调用的函数,只允许你想要的函数,并且创建自己想要控制的任何内容的版本。有几种方法可以做到这一点,它们各有优缺点,没有一个是不可打破的,你所能做的就是提高打破“监狱”所需的经验、努力和时间的门槛。
这意味着你必须在 C API 层面工作,但我并不建议修改源代码,除非你非常熟悉它并且可以轻松确定你的修改不容易被打破。通过停留在 C API 层面,至少其他 Lua 用户可以帮助验证沙箱的可靠性。
你必须想出一种方法,使你的代码可以调用 Lua 的内置函数,同时又不允许用户调用内置函数。我相信你可以在 lua 注册表中存储表,只有 C 代码可以查看。这已经有一段时间了。或者,如果你不把 getmetable 放在用户环境中,那么你就可以通过 metatable 调用内置函数,但用户无法访问它们。
例如,在 C 中:
- 你加载像 io 模块这样的内置模块,并在 (元)表中保存你要包装的函数(如 open);
- 从 _G 中删除 io 内置表,这样用户只能访问你创建的版本;你已经保存了稍后需要的函数
- 创建一个名为 io 的全局表,并将其元表设置为步骤 1 中创建的表,这样它只定义你想要给予访问权限的函数,如名为“open”的函数。
- 在该函数中,你可以在调用保存的内置函数之前做任何必要的过滤。
细节将产生很大的差异,如果你使用的是 Lua 5.1 还是 5.2,实现方式也会有所不同,但是网上有几篇关于在 Lua 中沙箱的好文章(很抱歉没有时间找),看看并想出一些方法,然后可能在 Lua 用户邮件列表或 SO 上发布一下,寻求专业人士的建议。;)
2013-12-21 13:41:56
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
打开 liolib.c 文件,进入下面这三个函数:
static void opencheck (lua_State *L, const char *fname, const char *mode) { LStream *p = newfile(L); p->f = fopen(fname, mode); if (p->f == NULL) luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno)); } static int io_open (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); LStream *p = newfile(L); const char *md = mode; /* to traverse/check mode */ luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode"); p->f = fopen(filename, mode); return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; } static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); LStream *p = newprefile(L); p->f = lua_popen(L, filename, mode); p->closef = &io_pclose; return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; }这些是您想要编辑的函数。
第一个函数将文件名作为参数
fname接收,第二个和第三个 将其作为局部变量filename从 lua 栈中弹出。现在你所需要做的就是:
1)获取自己的进程路径
2)规范给定的文件路径
3)比较它们,使它们在最后一个斜杠之前是相同的
4)如果它们不相同,则在
opencheck中使用luaL_error(L,"access denied to %s", fname);,其他两个函数中使用return luaL_fileresult(L,0,filename);。