I wanted to be sure that the function below is a 100% safe attack for code injection. In particular, can anyone find the function argument below, which allows the caller to get the table with the Lua executable code in it, or force the compilation \ exec to pass something through the function argument?
(I used this off-beat method because in my application functions such as shared routines and a debug library are limited, etc. Function calls will know about the text key restriction of the function argument, see below)
Attempt # 1: (FAIL / unsafe)
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
s = "return"..string.gsub(s, "function", "fun\\99tion")
local jail = {}
local f, err = load(s, "string2table:", "t", jail)
if err then return nil, err end
local ok, torErrmsg = pcall(f)
if not ok then return nil, torErrmsg end
return torErrmsg
end
"{s = \"function\"}"
"{f = (function () while true do end end)()}"
"{[(function () while true do end return 123 end)()] = 456}"
"{a = t.IdontExist}"
]]
Thanks everyone for the great feedback. Especially Yegor.
№2 . № 2 - , . s = "{( ''): Rep (99): (() '*. ': Rep (99)..' ')}"
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
s = "return"..string.gsub(s, "function", "fun\\99tion")
local jail = {}
string_mt.__index = nil
local f, err = s_load(s, "string2table:", "t", jail)
if err then return nil, err end
local ok, torErrmsg = pcall(f)
string_mt.__index = string
if not ok then return nil, torErrmsg end
return torErrmsg
end
end
"{s = \"function\"}"
"{f = (function () while true do end end)()}"
"{[(function () while true do end return 123 end)()] = 456}"
"{a = t.IdontExist}"
"{('a'):rep(99):find(('.*'):rep(99)..'b')}"
]]