2015-12-21 86 views
0

现在我正在做很多。创建一个安全的Lua沙箱..?

local env = { 
    print = print, 
} 

setfenv(FUNC,ENV) ,然后用元方法来锁定实例propertys,但它确实是效率低下,有很多旁路的。我GOOGLE了它,我发现的一切都是这样的:不工作。

+1

你指的是什么“旁路”?沙盒意味着脚本只能访问您明确允许的内容。考虑到你显示的代码,'func'只能访问'print'和你调用的任何参数。 –

+0

“假设我想访问getfenv()以及。“如果你不想让人们走进你的家,你不会给他们钥匙,这里也是这样:如果你不想让人们跳出沙箱,*不要*给他们工具所以任何好的沙箱都会阻止你使用'getfenv' –

+0

@Nicol但是更好的沙箱将允许沙箱访问*任何*当我想到一个沙箱时,我想它就像是我自己的沙发世界,我可以安全地执行任何操作,而无需访问“父环境”,例如getfenv(2)会因为“父环境”不存在而出错(好了,但是这不应该在沙箱内部看到)。 ) – warspyking

回答

3

在Lua 5.1中,沙盒很简单。如果你在一个文件中的Lua中的某个地方,并要防止其访问比您提供的参数以外的任何功能或任何东西,你这样做:

local script = --Load the script via whatever means. DO NOT RUN IT YET! 
setfenv(script, {}) 

script现在是沙箱。它不能访问除您直接提供的值之外的任何内容。它创建的函数无法访问此沙箱环境以外的任何内容。您的原始全球环境与它们完全隔绝,除非您允许它访问。

显然你可以把你喜欢的东西放在那张表中;该表将包含您喜欢的任何全球可访问的东西。您应该可以让Lua脚本访问基本的Lua标准库函数;大多数是纯粹的功能,不能做任何不愉快的事情。

下面是Lua的标准库的完整清单,你不得如果要保持正直沙箱给用户访问:

  • getfenv。用户有足够的理由能够setfenv,以便它可以在沙箱中创建自己的迷你沙箱。但是,如果要保持沙箱的完整性,则无法访问放置在沙箱中的任何功能的环境。
  • getmetatable:与上面相同的推理;设置metatables是可以的。虽然恶意代码如果改变其metatable可能会破坏对象,但恶意代码可能会通过无限循环而破坏整个系统。
  • 整个debug库。通过调试库可以进行所有的调试。

你也显然需要解决this problem that Lua 5.1 has with loading bytecode from within a Lua script。这可以用来打破沙箱。不幸的是,Lua 5.1并没有真正的好工具。在Lua 5.2+中,可以封装loadloadfile,这样无论用户提供什么,都可以在内部传递“t”作为模式参数。但是对于Lua 5.1,你需要一些方法来封装load et.al.这样您就可以知道数据何时为文本,何时不是。你可以通过阅读Lua源代码来找到Lua用来区分字节码和文本的代码。

或者您可以完全拒绝load及其朋友。

如果要防止用户对系统执行丑陋的操作,请禁止使用osio库。

+1

我可能值得一提的是,在“禁止访问”一节中禁用'loadstring'或者至少需要使用'loadstring'加载字节码也是需要的:https://gist.github.com/corsix/6575486 –

+0

@PaulKulchenko:谢谢你的提示。我认为LuaJIT没有这个特定的问题,因为使用了不同的字节码格式(尽管可能使用LuaJIT字节码来破解沙箱)。 –

+1

@NicolBolas你的意思是这样的? https://www.corsix.org/content/malicious-luajit-bytecode ;-)没有加载库。 (除jit(用于jit编译),但未在代码中引用/使用它。)对于任何类型的沙盒,请确保避免所有字节码加载。 – nobody