Lua沙盒具有泄漏的特殊功能
我正在尝试使用 如何创建安全的 Lua 沙箱? 构建我自己的泄漏沙箱。
我正在尝试创建一个Lua沙箱,其中一些Lua函数可以访问沙箱之外的其他一些Lua函数。例如,我希望我的沙箱有一个特殊的“显示”功能,它可以调用“打印”,但沙箱中也没有“打印”。
主要问题是我试图在已经很大的代码库中构建一个沙箱,所以我不能删除函数。
这怎么可能?
解决方案必须是纯 Lua 函数,这不是我的错。
I am trying to use How can I create a secure Lua sandbox? to build my own leaky sandbox.
I am trying to create a Lua sandbox where some Lua functions can access some other Lua functions outside the sandbox. For example I want my sandbox to have a special "display" function which can call "print" but not have "print" in the sandbox too.
The main problem is that I am trying to build a sandbox within an already large codebase, so I cannot nil away functions.
How is this possible?
The solution has to be a pure Lua function due to no fault of mine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
创建沙箱时,您可以通过从更大的环境中挑选函数和值来创建新的沙箱环境。您不需要破坏或“消除”原始环境中的任何内容。
因此,
打印
而
失败
When you create a sandbox, you do it by cherry picking functions and values from a larger environment to create a new sandbox environment. You do not need to destroy or "nil out" anything in the original environment.
So,
prints
whereas
fails with
是不是特别需要调用Lua标准库的
print
函数?您可以模拟print
的功能吗?因为那将是最简单的方法。但是,如果您想要对 print 进行包装,有两种方法可以实现:使用纯 Lua 代码和使用 C/C++ 代码。
纯Lua解决方案如下。请注意,这应该在加载任何外部脚本之前完成。首先,打开包含
print
的Lua标准库。然后运行这个 Lua 脚本:这将返回“display”函数。如果您愿意,您可以将其存储在名为
display
的全局变量中,或者称为其他名称。之后,您可以
nil
输出print
全局变量,从而使其几乎完全无法访问。如果您想从 C/C++ 执行此操作,则非常相似。首先,像以前一样,您注册包含
print
的 Lua 标准库,以便您可以获得它的函数。然后,使用 lua_getglobal(L, "print") 来获取 print 函数并将其压入堆栈。接下来,使用lua_pushcclosure
注册 C/C++ 函数。但是你想指定一个上值,Lua 在注册时从堆栈中弹出该值。现在,您注册的函数位于堆栈上,等待被推入 Lua 变量或全局表条目中。
警告:Lua 调试库可以查看上值,从而从新函数中获取
print
函数。因此,如果您想要完美的安全性,请摆脱debug.getupvalue
。Does it specifically need to call the Lua standard library
print
function? Can you instead emulate the functionality ofprint
? Because that would be the easiest way.However, if you want to have a wrapper around
print
, there are two ways to do it: with pure Lua code, and with C/C++ code.The pure Lua solution is as follows. Note that this should be done before loading any external scripts. First, open the Lua standard library that has
print
in it. Then run this Lua script:This will return the "display" function. You can store it in a global variable called
display
if you like, or called something else.After that, you can
nil
out theprint
global variable, thus making it almost entirely inaccessible.If you want to do it from C/C++, it's very similar. First, as before, you register the Lua standard library that includes
print
, so that you can get the function for it. Then, you uselua_getglobal(L, "print")
to get theprint
function and push it onto the stack. Next, you register your C/C++ function using usinglua_pushcclosure
. But you want to specify one upvalue, which Lua pops off the stack at registration time.And now your registered function is on the stack, waiting to be pushed into a Lua variable or global table entry.
Warning: the Lua debug library can poke at upvalues and thus get the
print
function from your new function. So if you want perfect security, get rid ofdebug.getupvalue
.构建您的沙箱(或多个沙箱,如果每个沙箱都有不同的要求)并将不受信任的代码一次移入沙箱中一部分。在我的快速 cli 测试中,5.1 和 5.2 都将运行在沙箱外部定义的函数,无需修改。要使用 Doug 的示例,假设
display
是使用print
的现有代码的一部分:请注意,在上述两个示例中,
display
> 函数正在使用print
而不修改该代码,因为创建此函数时您不在沙箱中。过去,我存储了一个指向非沙盒环境的本地指针,但我无法重现快速 cli 测试中需要的情况。如果您能举出一个示例,我可能会想出一种不需要
e
变量的解决方法。下面是使用 5.2 的代码示例:另一个示例,对于我的只读表代码,我再次使用
e
:Build your sandbox (or multiple sandboxes if they each have different requirements) and move the untrusted code into the sandbox one piece at a time. In my quick cli tests, both 5.1 and 5.2 will run functions that were defined outside of the sandbox without modification. To use Doug's example, assume
display
is part of your pre-existing code that usesprint
:Note that in both of the above examples, the
display
function is usingprint
without modification to that code since you were not in the sandbox when this function was created.In the past, I've stored a local pointer to the un-sandboxed environment, but I can't reproduce the situation where that's needed in my quick cli tests. If you can come up with an example, I can probably come up with a workaround that doesn't require the
e
variable. Here's an example of that code using 5.2:another example, for my read only table code, I'm again using the
e
: