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 Windo开发者_如何学JAVAw:
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?
--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.)
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.
精彩评论