Hello,
When using ImportPackages in lua, there is a glitch that may lead to random code execution on the server (and through this it may compromise the server safety and/or leak data).
The cause of the bug is that when you use AddFunctionExport, you add a single function to export, not the whole context. However, that context may be used in the return value of the exported function and jumped on in the ImportPackages' size. In this case, you will access to a random point of memory, usualy one that have been freeed by lua's garbage collector.
Here is a demonstration of the problem :
objects.lua file, in the toolslib package
The important thing here is that the returned object include a lambda, but this lambda will never be exported itself since the object is not the function. Now if you do :
server.lua file, in the mytest package
The instant this code is run, your server will segf. It also works with function returning functions, like this :
This will raise a lua error, stating that we are trying to call nil - because test is no longer defined. Of course, both examples works fine when used in the same package, since references are correct.
This problem may lead to important concerns, especialy if we want to start using an external library - since any compromission in the external library may lead not only to our game server crash, but also the whole physical / virtual server vulnerability :/
I'm not exactly certain on how this could be solved. A way could be to remove ImportPackage support altogether and allow using require on client : that would allow to access potentially "private" functions (although there are some way in lua to prevent that). I guess there is some kind of pseudo-isolation between lua packages that would be broken by this method, but it would give more security and more flexibility to create scripts. That would also prevent some loadstring based hack that could be used now to get the files and that could add some more vulnerabilities both on the server and the client side.
Another way could be to map importpackage function to get their context and import the exported function's context into the importing module : that would probably remove the problem but that could create some name collision that may create hard-to-find bugs.
I hope you'll find a way around this ! Please feel free to ask if I omitted any element.
Thank you !
When using ImportPackages in lua, there is a glitch that may lead to random code execution on the server (and through this it may compromise the server safety and/or leak data).
The cause of the bug is that when you use AddFunctionExport, you add a single function to export, not the whole context. However, that context may be used in the return value of the exported function and jumped on in the ImportPackages' size. In this case, you will access to a random point of memory, usualy one that have been freeed by lua's garbage collector.
Here is a demonstration of the problem :
objects.lua file, in the toolslib package
Code:
function NewObject() local result = { new=function () return 42 end } return result end AddFunctionExport("Object", NewObject)
server.lua file, in the mytest package
Code:
tools = ImportPackage("toolslib") MyObject = tools.Object()
Code:
function myfunc() function test(a) print(a) end return test end AddFunctionExport("test", myfunc)
Code:
test = ImportPackage("toolslib") test()(2)
This problem may lead to important concerns, especialy if we want to start using an external library - since any compromission in the external library may lead not only to our game server crash, but also the whole physical / virtual server vulnerability :/
I'm not exactly certain on how this could be solved. A way could be to remove ImportPackage support altogether and allow using require on client : that would allow to access potentially "private" functions (although there are some way in lua to prevent that). I guess there is some kind of pseudo-isolation between lua packages that would be broken by this method, but it would give more security and more flexibility to create scripts. That would also prevent some loadstring based hack that could be used now to get the files and that could add some more vulnerabilities both on the server and the client side.
Another way could be to map importpackage function to get their context and import the exported function's context into the importing module : that would probably remove the problem but that could create some name collision that may create hard-to-find bugs.
I hope you'll find a way around this ! Please feel free to ask if I omitted any element.
Thank you !
Comment