This super simple and fast mechanism executes everything in savedata.lua. The trouble with it is you have to trust that the file hasn't been maliciously constructed to attack you.
Yeah, you can use setfenv but that's not enough, there are tricks around that. You also need to be careful with the string metatable, for example, and with possible bytecode.
My favourite Lua serialization/deserialization libraries that don't write Lua code are bitser, for a binary and compact format, and Smallfolk, for a user-readable text format, both of which happen to be written by the same author.
PolySaken wrote: ↑Sat Aug 14, 2021 8:10 am
Easy to prevent arbitrary code execution by not including [icode]return[/icode] in the file and just concatenating it in the loader instead.
PolySaken wrote: ↑Sat Aug 14, 2021 8:10 am
Easy to prevent arbitrary code execution by not including [icode]return[/icode] in the file and just concatenating it in the loader instead.
local savedata = {}
local savechunk = loadfile('save.lua', 't', savedata)
if pcall(savechunk) then
print(savedata.foo, table.concat(savedata.baz, ' '))
else
error('Invalid save data')
end
The only "attack vector" here are loops, but they can't do more than crash/hang/OOM the loader and there are several ways to mitigate that risk if required.
I'd prefer to use this for configuration purposes over JSON/ini or custom formats. Lua was born as a configuration language after all. I wouldn't use it for save files though, because serializing to Lua seems like a hassle. It's also not particularly fast. A well-written parser for a custom format would easily be faster than loadfile.
grump wrote: ↑Sat Aug 14, 2021 2:58 pm
The only "attack vector" here are loops, but they can't do more than crash/hang/OOM the loader and there are several ways to mitigate that risk if required.
If I understood you right, sending in the 'savedata' blank table will disable access to modules such as 'os' that's needed for the attack that Pgimeno showed?
The json.lua lib seems minimal enough to add to a game. Set a table with all your values, encode it as a JSON string and write it to a file with love.filesystem.write, observing that the file will be written to the game's "save directory", the path to which depends on some circumstances that you can read about in here: https://love2d.org/wiki/love.filesystem