6

I'm trying to embed some Lua scripting functionality in my C# app by using LuaInterface 2.0.3. This is working just fine so far, but I can't figure out how to restrict access to only few specified .Net classes. By default, all .Net libraries are directly accessible through "luanet" and Lua scripts are free to open new windows or access the file system.

e.g. this Lua script will open a new Window:

   Form = luanet.System.Windows.Forms.Form
   mainForm = Form()
   mainForm:ShowDialog()

Freedom of scripting is great and all, but this is likely to interfere with the hosting app and has some security-related implications I'm not too fond of. Is there any way to disable this?

Mario
  • 413
  • 5
  • 15
  • It's possible that this would get a better response on Games Development, http://gamedev.stackexchange.com/. It is something that game devs are more likely to have done in the past, and appears to be about game development anyway. – Glenn May 30 '11 at 01:29
  • 1
    A less specific question on sandboxing Lua, which may point you in the right direction, is here: http://stackoverflow.com/questions/1224708/how-can-i-create-a-secure-lua-sandbox – BMitch May 30 '11 at 01:38

2 Answers2

9
--make a table for all the classes you want to expose
safeClasses = {}
--store all the ones you want
safeClasses.Form = luanet.System.Windows.Forms.Form
--etc...

--remove access to LuaInterface
luanet = nil
package.loaded.luanet = nil
--prevent future packages from being loaded
require = nil
package.loadlib = nil

You could also do this in reverse, removing the global and stored instances of LuaInterface first and then doing all the work through a local reference (which all code in the rest of the block can use):

--get a local reference to LuaInterface without clobbering the name
local luainterface = luanet

--delete the global reference to it
luanet = nil

--also delete it from the package store and disable package loading
package.loaded.luanet = nil
require = nil
package.loadlib = nil

--put luanet back locally at its original name (for convenience)
local luanet = luainterface 

--make a table for all the classes you want to expose
safeClasses = {}
--store all the ones you want
safeClasses.Form = luanet.System.Windows.Forms.Form
--etc...

(You can avoid the three-step name-preservation dance above (local luainterface=luanet; luanet=nil; local luanet=luainterface) by localizing directly to luanet and then deleting the global through the _G reference to the global table:

local luanet=_G.luanet
_G.luanet = nil

I just chose not to as a matter of personal preference.)

Stuart P. Bentley
  • 10,195
  • 10
  • 55
  • 84
  • Only had a quick look at it, but this looks excellent already. I guess, my error was to assume this has to be done in C# by somehow setting up or configuring the Lua interpreter differently - didn't realize the sandboxing could be done directly in Lua. – Mario May 30 '11 at 02:21
  • Tested it in my app - this is **exactly** what I was looking for. Combined with this [link](http://lua-users.org/wiki/SandBoxes) article I should now be able to construct a proper sandbox for my Lua scripts. Thanks! :) – Mario May 30 '11 at 10:06
0

I'm not really sure about how exactly you would go about it, but the first step should be hosting it in an extra AppDomain. With that extra appdomain, you have granular control of what modules can be used and which can't, however, it will add extra work to get data moved between your main program and the script.

The AssemblyLoad/AssemblyResolve events should be your first stop.

Femaref
  • 60,705
  • 7
  • 138
  • 176
  • I don't think this'll be performant enough exactly because of that "extra work". Lua is supposed to drive game logic such as AI or mission scripts... not sure if cross-AppDomain communication would be up for that task, but I have little experience with that, so... yeah. :/ – Mario May 30 '11 at 01:05