清理Lua表输入

时间:2013-10-08 21:33:31

标签: lua lua-table

假设我想要一个Lua表,它将从第三方提供,而不是完全可靠,来自文件或其他IO源。

我将表格作为字符串,例如“{['valid'] = 10}”,我可以将其加载为

externalTable = loadstring("return " .. txtTable)()

但这会打开代码注入的漏洞,即:txtTable = os.execute('rm -rf /')

所以我做了这个消毒功能:

function safeLoadTable(txtTable)
    txtTable = tostring(txtTable)
    if (string.find(txtTable, "(", 1, true)) 
        then return nil end
    local _start = string.find(txtTable, "{", 1, true)
    local _end = string.find(string.reverse(txtTable), "}", 1, true)
    if (_start == nil or _end == nil)
        then return nil end
    txtTable = string.sub(txtTable, _start,  #txtTable - _end + 1)
    print("cropped to ", txtTable)
    local pFunc = loadstring("return " .. txtTable)
    if (pFunc) then
        local _, aTable = pcall(pFunc)
        return aTable
    end
end

在最坏的情况下,它应该返回零。 这可以被认为是安全的,反对“常规的恶意人”:)

4 个答案:

答案 0 :(得分:1)

我认为这不安全。试试这个:

print(safeLoadTable [[{ foo = (function() print"yahoo" end)() } ]])

修改

或者这个,为了更多的乐趣:

print(safeLoadTable [[{ foo = (function() print(os.getenv "PATH") end)() } ]])

尽管如此,我还是不建议将os.getenv替换为os.execute。 : - )

问题不容易解决。在这种情况下,代码注入避免并不简单,因为在执行loadstring时您正在执行一段Lua代码。没有简单的字符串匹配技术真的很安全。唯一安全的方法是为Lua表语法的子集实现解析器,并在字符串上使用该解析器。

顺便说一句,即使Lua团队从Lua 5.2中剥离了字节码验证程序,因为他们发现它可以攻击,字节码是比Lua源代码简单得多的语言。

答案 1 :(得分:1)

您可以在沙箱中运行不安全的代码。

以下是一个简单的沙盒在Lua 5.1中的外观(为简洁省略了错误处理):

local script = [[os.execute("rm -rf /")]]
local env = { print=print, table=table, string=string }
local f, err = loadstring(script)
if err then
   -- handle syntax error
end
setfenv(f, env)
local status, err = pcall(f)
if not status then
   -- handle runtime error
end

在Lua 5.2中,您可以使用load函数将脚本加载到自己的环境中。

结果将是从pcall返回的运行时错误:

attempt to index global 'os' (a nil value)

修改

正如Lorenzo Donati在评论中指出的那样,这不是阻止流氓脚本的完整解决方案。它基本上允许您列出批准用户脚本的函数和表。

有关处理流氓脚本的更多信息,我建议这个问题: Embedded Lua - timing out rogue scripts (e.g. infinite loop) - an example anyone?

答案 2 :(得分:1)

我正是为了这个目的创建了sandbox.lua。假设您的环境可以访问debug工具,它将处理不安全的东西以及DOS类型的攻击。<​​/ p>

https://github.com/kikito/sandbox.lua

请注意,目前仅与Lua 5.1兼容。

答案 3 :(得分:0)

在沙箱中运行并不安全,检查源代码并不是很简单。一个想法:检查字节码!

嗯,实际上这也不是很简单,但这是一个懒惰的实现:http://codepad.org/mGqQ0Y8q