gpt4 book ai didi

serialization - 这安全吗? (反序列化)

转载 作者:行者123 更新时间:2023-12-01 06:02:30 25 4
gpt4 key购买 nike

我想确保下面的函数是 100% 安全的 wrt 代码注入(inject)攻击。具体来说,任何人都可以找到下面函数的参数,允许调用者检索其中包含可执行 Lua 代码的表,或者使函数编译\执行通过函数参数传递给它的任何内容?

(我采用了这种另类的方法,因为协程和调试库等类似的东西在我的应用程序中受到限制。函数调用者将知道参数的“函数”文本键约束;见下文)

尝试#1:(失败/不​​安全)

--[[ string2table(s : string)

De-serialise the string argument into a Lua table.

s should define a string serialised Lua constructor

However, no value of s can:
embed any code that can be executed at any stage by the caller
cause a runtime error during exec of the function

Pre:
Requires Lua v5.3
string2table() is in the global env.
The caller has no acccess to load or pcall. i.e the caller is in a jail

s should represent a serialised Lua constructor as a string starting with "{".
s cannot not be pre-compiled or the function will return an error.
s must not encode any table key containing the text "function".

Return Value:

On success

table : s de-serialised into a lua table. Bascially pcall(load(s))

On fail

nil, errmsg
]]

function string2table(s)
if type(s) ~= "string" then return nil, "call format: string2table(string)" end
if string.find(s, "{") ~= 1 then return nil, "string arg must begin with '{'" end -- just a hint, this affords no protection
s = "return"..string.gsub(s, "function", "fun\\99tion") -- NB \99 = "c"
-- The return & gsub above prevents embedding any code in s.
-- Specifically re the gsub:
-- when the text 'function' appears in a lua string it gets converted to 'function' ie no effect.
-- when the text 'function' appears outside of a lua string it gets converted to 'fun\99tion' causing the pcall to fail.
-- The cost of the gsub aprroach is that s can't define any table key with the text "function" in it.
-- However any "function" text embedded in a string will be unaffected.

local jail = {}
local f, err = load(s, "string2table:", "t", jail)
if err then return nil, err end -- it didnt compile, return the error
local ok, torErrmsg = pcall(f)

if not ok then return nil, torErrmsg end -- runtime error occured
return torErrmsg -- all ok, return the table
end

--[[ Example arguments:

"{s = \"function\"}" -- rv = true, {s = "function"}
"{f = (function () while true do end end)()}" -- value is a function call; rv = nil, [string "string2table:"]:1: ')' expected near '\'
"{[(function () while true do end return 123 end)()] = 456}" -- key is a function call; rv = nil, [string "string2table:"]:1: ')' expected near '\'
"{a = t.IdontExist}" -- runtime error; rv = nil, [string "string2table:"]:1: attempt to index a nil value (global 't')

]]

感谢大家的好评。尤其是叶戈尔。

根据初始反馈尝试#2。尝试 #2 现在还禁用字符串库元方法,例如s="{('a'):rep(99):find(('.*'):rep(99)..'b')}"
--[[ string2table(s : string)

De-serialise the string argument into a Lua table.

s should define a string serialised Lua constructor

However, no value of s can:
embed any code that can be executed at any stage by the caller
cause a runtime error during exec of the function

Pre:
Requires Lua v5.3
string2table() is in the global env.
The caller has no acccess to load or pcall. i.e the caller is in a jail
Assumes the string library is present/visible.

s should represent a serialised Lua constructor as a string starting with "{".
s cannot not be pre-compiled or the function will return an error.
s must not encode any table key containing the text "function".

Warning:
Inefficient (invokes Lua compiler).
Recommend JSON & JSON lib for frequent use over this function.

Return Value:

On success

table : s de-serialised into a lua table. Bascially pcall(load(s))

On fail

nil, errmsg
]]

do

local s_load = load
local string_mt = getmetatable("")

function string2table(s)
if type(s) ~= "string" then return nil, "call format: string2table(string)" end
if string.find(s, "{") ~= 1 then return nil, "string arg must begin with '{'" end -- just a hint, this affords no protection
s = "return"..string.gsub(s, "function", "fun\\99tion") -- NB \99 = "c"
-- The return & gsub above prevents embedding most code from being embedded in s.
-- Specifically re the gsub:
-- when the text 'function' appears in a lua string it gets converted to 'function' ie no effect.
-- when the text 'function' appears outside of a lua string it gets converted to 'fun\99tion' causing the pcall to fail.
-- The cost of the gsub aprroach is that s can't define any table key with the text "function" in it.
-- However any "function" text embedded in a string will be unaffected.

-- gsub option: string.gsub(s, "%f[%w_]function%f[^%w_]", "fun\\99tion")
-- This variation above should safely allows keys with ..'function'.. in the key text to still load e.g. "{functional = true}"
-- [ed: I simply havent used this alt. gsub yet because im still learning Lua patterns and %f still confuses me]

local jail = {}

local f, err = s_load(s, "string2table:", "t", jail) -- "t" means only text chunks
if err then return nil, err end -- it didnt compile, return the error

-- The string library's metatable represents a gaping hole in the jail. Temporarily close it.
-- This will ensure strings like this "{('a'):rep(99):find(('.*'):rep(99)..'b')}" are caught as an error.
string_mt.__index = nil -- disable string lib metatable

local ok, torErrmsg = pcall(f)

string_mt.__index = string
if not ok then return nil, torErrmsg end -- runtime error occured
return torErrmsg -- all ok, return the table
end
end

--[[ quick test cases:

"{s = \"function\"}" -- rv = true, {s = "function"}
"{f = (function () while true do end end)()}" -- value is a function call; rv = nil, [string "luaDoStringLua:simple"]:1: ')' expected near '\'
"{[(function () while true do end return 123 end)()] = 456}" -- key is a function call; rv = nil, [string "luaDoStringLua:simple"]:1: ')' expected near '\'
"{a = t.IdontExist}" -- runtime error; rv = nil, [string "luaDoStringLua:simple"]:1: attempt to index a nil value (global 't')
"{('a'):rep(99):find(('.*'):rep(99)..'b')}" -- If string if exec'd it will hang the Lua interpreter.
]]

最佳答案

我找不到任何破解它的方法。你可以得到jail通过这样做在 Lua 5.2+ 中的表:

local jail = string2table("{_ENV}")[1]

但是如果你在 string2table之后添加东西到 jail 表中也没关系。运行,因为每次都会生成一个新的 jail 表。 (只是不要重复使用表格!)

但是,我认为我对 Lua 沙盒的了解还不足以宣布它是安全的。我可能忽略了一些事情。

另外,考虑替换 string.find(s, "{") ~= 1string.sub(s, 1, 1) ~= "{" .这样您就不必搜索整个字符串来检查第一个字符是否是左大括号。

关于serialization - 这安全吗? (反序列化),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44062039/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com