对Lua表输入进行清理处理

假设我需要一个 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

最坏的情况下应该返回 nil。 可以认为这是安全的,可以抵御“一般的恶意人” :)

点赞
用户2633423
用户2633423

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

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源代码要简单得多。

2013-10-08 21:40:51
用户415823
用户415823

你可以在沙盒中运行不安全的代码。

以下是 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
   -- 处理语法错误
end
setfenv(f, env)
local status, err = pcall(f)
if not status then
   -- 处理运行时错误
end

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

结果会从 pcall 返回运行时错误:

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

编辑

正如 Lorenzo Donati 在评论中指出的那样,这不是防止恶意脚本的完整解决方案。它本质上只是允许您白名单为用户脚本批准的函数和表格。

有关处理恶意脚本的更多信息,建议查看以下问题: 嵌入式 Lua - 计时恶意脚本(例如无限循环) - 任何示例?

2013-10-08 21:52:18
用户2733013
用户2733013

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

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

2013-10-09 16:32:16
用户312586
用户312586

我特别为此目的创建了 sandbox.lua。它将处理不安全的内容和DOS类型的攻击,假设你的环境可以访问 debug 设备。

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

注意,目前它只兼容Lua 5.1。

2013-10-10 18:46:08