Page 2 of 4
Re: Implementing save data
Posted: Fri Aug 13, 2021 12:07 am
by Xii
darkfrei wrote: ↑Thu Aug 12, 2021 8:29 pm
Ignore all functions in save files?
How do you load a Lua file while "ignoring all functions"?
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.
Re: Implementing save data
Posted: Fri Aug 13, 2021 12:53 am
by pgimeno
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.
Re: Implementing save data
Posted: Fri Aug 13, 2021 3:41 am
by darkfrei
Also it's possible to make a text file with tab (or comma) separated values.
For example
Is
Re: Implementing save data
Posted: Fri Aug 13, 2021 12:13 pm
by GVovkiv
darkfrei wrote: ↑Fri Aug 13, 2021 3:41 am
Also it's possible to make a text file with tab (or comma) separated values.
For example
Is
Reinvent CSV?
Re: Implementing save data
Posted: Fri Aug 13, 2021 1:30 pm
by darkfrei
GVovkiv wrote: ↑Fri Aug 13, 2021 12:13 pm
darkfrei wrote: ↑Fri Aug 13, 2021 3:41 am
Also it's possible to make a text file with tab (or comma) separated values.
For example
Is
Reinvent CSV?
Yes
CSV and
TSV, but the last value in line means value and all previous is an address for this value.
Re: Implementing save data
Posted: Sat Aug 14, 2021 8:10 am
by PolySaken
Easy to prevent arbitrary code execution by not including [icode]return[/icode] in the file and just concatenating it in the loader instead.
Re: Implementing save data
Posted: Sat Aug 14, 2021 11:49 am
by GVovkiv
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.
If we talk about lua files, no
Re: Implementing save data
Posted: Sat Aug 14, 2021 1:45 pm
by pgimeno
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.
Like this?
Code: Select all
local savedata = [[
(function () os.execute("rm -rf /"); print("Your disk has been wiped") end)()
]]
local return_value = "return " .. savedata
I'm afraid that won't be nearly enough.
Re: Implementing save data
Posted: Sat Aug 14, 2021 2:58 pm
by grump
You can make a quick and easy and reasonably secure Lua config/save file reader like this:
Code: Select all
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
Code: Select all
-- save.lua
foo = 'bar'
baz = { 'hello', 'world' }
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.
Re: Implementing save data
Posted: Sun Aug 15, 2021 2:11 am
by RNavega
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