Forums » Suggestions
Lua - Access to metatables
I would like to request access to metatables within the sandbox.
While metatables are a powerful way to extend behavior and functionality, I can't currently see how they might undermine the security of the sandbox environment. This may be partly due to my lack of experience with them due to them not being available in the VO sandbox environment.
At a minimum this would allow us to create more natural objects for those that prefer an object-oriented approach to programming.
I've had other reasons in the past to want to use them, but I have since forgotten particulars.
While metatables are a powerful way to extend behavior and functionality, I can't currently see how they might undermine the security of the sandbox environment. This may be partly due to my lack of experience with them due to them not being available in the VO sandbox environment.
At a minimum this would allow us to create more natural objects for those that prefer an object-oriented approach to programming.
I've had other reasons in the past to want to use them, but I have since forgotten particulars.
At a guess, I'd hazard there's two main security concerns:
i) there's some plugin-accessible object X whose metatable contains information plugins shouldn't be able to know, and/or
ii) there's some plugin-accessible object X whose metatable controls something plugins aren't supposed to be able to control.
If my guess is correct, then it should still be possible to add a secure version of getmetatable/setmetatable by adding one new function a bit like:
```
local plugin_metatables = {} -- outside of sandbox
sandbox.newmetatable = function()
local r = {}
plugin_metatables[r] = true
return r
end
sandbox.getmetatable = function(object)
if not plugin_metatables[object] then error('...') end
return getmetatable(object)
end
sandbox.setmetatable = function(table, metatable)
if not plugin_metatables[table] then error('...') end
return setmetatable(table, metatable)
end
... and so on for rawget/rawset/rawequal
```
This would mean that the functions can only operate on guaranteed-safe tables. There's still opportunity for some weird stuff - you could use .__len and pass your table to a VO function to maybe make it think your list is longer/shorter than it actually is - but for the most part it /seems/ like it should be safe. Worst-case would involve checking the args of each plugin-accessible VO function and erroring if you find any argument in `plugin_metatables`.
(Not to step on the devs' toes. For all I know this is 1000x more difficult than I think it "should be".)
(Or maybe my guess is wrong / there aren't any such tables and this isn't useful lol)
I'd also really like metatable support to be added. I often find myself making ugly workarounds for stuff that metatables are designed for. Eg. adding a bunch of poorly-coordinated stuff called :len() or :length() or .n to emulate .__len, or :set() or :put() to emulate .__newindex, and so forth. OO stuff like "what's the type of this object?" is a lot more haphazard and complicated too.
There's also a few pure-lua libraries I've looked at, but they make use of metatables in ways that's complicated to disentangle, to the point that I just give up spend a few days/weeks to write my own. If we had metatable support, even with newmetatable(), that would make converting libraries for use in VO a lot more practical.
i) there's some plugin-accessible object X whose metatable contains information plugins shouldn't be able to know, and/or
ii) there's some plugin-accessible object X whose metatable controls something plugins aren't supposed to be able to control.
If my guess is correct, then it should still be possible to add a secure version of getmetatable/setmetatable by adding one new function a bit like:
```
local plugin_metatables = {} -- outside of sandbox
sandbox.newmetatable = function()
local r = {}
plugin_metatables[r] = true
return r
end
sandbox.getmetatable = function(object)
if not plugin_metatables[object] then error('...') end
return getmetatable(object)
end
sandbox.setmetatable = function(table, metatable)
if not plugin_metatables[table] then error('...') end
return setmetatable(table, metatable)
end
... and so on for rawget/rawset/rawequal
```
This would mean that the functions can only operate on guaranteed-safe tables. There's still opportunity for some weird stuff - you could use .__len and pass your table to a VO function to maybe make it think your list is longer/shorter than it actually is - but for the most part it /seems/ like it should be safe. Worst-case would involve checking the args of each plugin-accessible VO function and erroring if you find any argument in `plugin_metatables`.
(Not to step on the devs' toes. For all I know this is 1000x more difficult than I think it "should be".)
(Or maybe my guess is wrong / there aren't any such tables and this isn't useful lol)
I'd also really like metatable support to be added. I often find myself making ugly workarounds for stuff that metatables are designed for. Eg. adding a bunch of poorly-coordinated stuff called :len() or :length() or .n to emulate .__len, or :set() or :put() to emulate .__newindex, and so forth. OO stuff like "what's the type of this object?" is a lot more haphazard and complicated too.
There's also a few pure-lua libraries I've looked at, but they make use of metatables in ways that's complicated to disentangle, to the point that I just give up spend a few days/weeks to write my own. If we had metatable support, even with newmetatable(), that would make converting libraries for use in VO a lot more practical.
Wow I got really enthusiastic writing that post last night. Sorry for the wall of text. It's been too long to edit it anymore so: tldr; metatables make writing OO and using libraries easier, and it would very nice to have them.
I appreciate the interest, but honestly: security and exploit-related problems in the plugins infrastructure have occupied a substantial chunk our development time over the last couple of years. This is time that otherwise might have been put towards making new content and improving the game.
We did have an internal discussion about metatables a couple of months ago, because of draugath's post, and with the result being that we are not in favor of enabling support. It adds further complexity and uncertainty to a system that has already proven difficult for us to have confidence in the scope and range of potential abuse.
Just to reiterate a point from some other discussions, but the goal of the Plugin system was to allow players to iterate on UI/UX concepts that would then then be re-implemented by the developers and formally integrated into the game.
The idea was not (and never has been) to create a wholly-open modification structure in which players can add "absolutely anything" into the game.. this is not the goal, because the tradeoffs of of significant advantages that can be developed (which can start to get into the realm of "cheating" / "exploitation", especially at-scale), security problems, and in some cases, actual governmental regulatory concerns and related liabilities for us (a more recently emerging problem).
So, much like World of Warcraft's similarly locked-down Lua API, we have to be pretty cautious about balancing between "potential capabilities" and "potential problems".
At the present time, we do not intend to add support for metatables in the VO Lua API.
We did have an internal discussion about metatables a couple of months ago, because of draugath's post, and with the result being that we are not in favor of enabling support. It adds further complexity and uncertainty to a system that has already proven difficult for us to have confidence in the scope and range of potential abuse.
Just to reiterate a point from some other discussions, but the goal of the Plugin system was to allow players to iterate on UI/UX concepts that would then then be re-implemented by the developers and formally integrated into the game.
The idea was not (and never has been) to create a wholly-open modification structure in which players can add "absolutely anything" into the game.. this is not the goal, because the tradeoffs of of significant advantages that can be developed (which can start to get into the realm of "cheating" / "exploitation", especially at-scale), security problems, and in some cases, actual governmental regulatory concerns and related liabilities for us (a more recently emerging problem).
So, much like World of Warcraft's similarly locked-down Lua API, we have to be pretty cautious about balancing between "potential capabilities" and "potential problems".
At the present time, we do not intend to add support for metatables in the VO Lua API.