On October 8, 2016, I discovered a means of escaping the sandbox from within it. That is, a way to access the global environment from the user scripting interface, without modifying any game files. This quickly led to discovering other means of escaping the sandbox. Some are easier/more practical than others, but the point is that there are a lot of them, and there's no way I've found all of them. I am not going to post them publicly right now.
This is very common in video games with mods.
The reason I'm mentioning this at all, then, is that it means malware mods are technically possible. It is entirely possible to make a dungeon that, when played, erases a bunch of files on your hard drive, opens shady porn sites in your Web browser, etc.
So, be careful what you download.
On the other hand, it's exciting for modders because it means now you can easily:
- change all manner of game mechanics that were previously off-limits, change standard GUI elements, even change things like lights' shadow distance
- dynamically generate textures and geometry, use custom shaders, and you can even render to textures so making your own effects like WaterSurfaceComponent reflection is possible; you can make mirrors, recursive reflections, even portals that show what's on the other side of the portal!
- change the save game code to avoid out of memory crashes
(yes, I've been doing all of these things)
This did not come as a surprise to me, because sandboxing Lua from Lua while still allowing data to pass through (the scripting interface would be rather pointless if you couldn't do anything to the dungeon) is nearly impossible. That means that patching these exploits out is nearly impossible, and, I would argue, pointless to even attempt - you would have to break existing non-malware mods to do so.
If you happen to be developing an application with a Lua interface and are worried about this, I believe the easiest way to make file writing and program execution off-limits is to cut off the global environment's access to io functions entirely, before any user Lua can run. As in
SpoilerShow
Code: Select all
_G.io = nil
Code: Select all
_G.debug = nil
Code: Select all
do
local io = _G.io
function writeAsdf()
local file = io.open("C:\Users\Steve\AppData\asdf.txt","w")
file:write("asdfasdfasdfasdfasdfasdf")
file:close()
end
_G.io = nil
end
(You can never make new C callbacks from Lua, so you don't need to worry about that. Unless you're using one of those modified Lua packages that can call arbitrary C functions. Don't use those, they are a portability nightmare.)