> Thanks so much for your work on lua-alchemy!
Thank you for your interest to our project!
> I was looking forward to Global Environment Protection and a few days
> ago the wiki page appeared, but I'm unsure whether it does what I'm
> looking for. The main reason I'm interested in lua-alchemy is because
> I'm working on a site that let's users write programs utilizing our
> APIs. So what I need is to jail the Lua script from accessing anything
> it's not supposed to. (Cookies for instance.)
> Can you please give me some pointers to what the right approach would
> be, whether lua-alchemy supports this and if not, where I should start
> looking to add such a feature?
What you want to achieve can be done. However, GEP is of little use here.
The Global Environment Protection feature is to protect code from
accessing undeclared global variables. If global variable is already
there, GEP does not do anything to prevent access to it.
What you need is to limit API available to users. In Lua this is often
called Sandboxing.
The key technique is to execute user's code in the separate,
sandboxed, environment:
local my_api =
{
some_api_function = function()
print("Hello, world!")
end;
}
local run_in_sandbox = function(users_code, my_api)
local res, err = loadstring(users_code)
if res then
setfenv(fn, my_api)
return pcall(fn)
end
end
run_in_sandbox([[some_api_function()]], my_api)
A few hints:
1. Never run user's bytecode, always compile from the source. You want
to replace loadstring, loadfile and load (also dofile) with thin
wrappers to do appropriate checks.
2. Provide to user's code only API which you allow it to use. Do not
provide anything else. You may find the list of sandbox-safe Core Lua
API functions in the wiki (see link below).
3. Lua Alchemy API is *not* sandbox-safe. Write with Lua Alchemy API
your own API that does only what you need to allow user to do, and
expose it.
4. You need to decide if you want to limit memory and CPU usage by
user's code. This is a bit harder to do, but quite possible. It may
require some work with Lua C API though. I'm actually interested in
adding built-in sandboxing support to Lua Alchemy, so I may help you
here.
You may find more hints on sandboxing at Lua wiki:
http://lua-users.org/wiki/SandBoxes
If you have further questions, please do not hesitate to ask them on
the list -- I'll be glad to help.
HTH,
Alexander.
One thin moment here. In this code my_api environment table is shared
between calls of user code. It may be not exactly what you want.
Simplest solution is to recreate it each time:
local make_my_api = function()
return
{
some_api_function = function()
print("Hello, world!")
end;
}
end
local run_in_sandbox = function(users_code, my_api)
local res, err = loadstring(users_code)
if res then
setfenv(fn, my_api)
return pcall(fn)
end
end
run_in_sandbox([[some_api_function()]], make_my_api())
HTH,
Alexander.
You're welcome!
>> 4. You need to decide if you want to limit memory and CPU usage by
>> user's code. This is a bit harder to do, but quite possible. It may
>> require some work with Lua C API though.
> Might scriptTimeLimit (http://tinyurl.com/d638mx) help here? Obviously
> it depends on the implementation details, but Alchemy and therefore
> Lua code is in principle still subject to the AVM2 execution time
> limit, no?
Looks good. I do not see any reason why this shouldn't work.
> That's unless flyield() is used of course in which case
> control would be returned anyway, so it would be possible to have
> another timer running, checking the script's runtime and - if
> necessary - killing it.
Just do not expose flyield() to user.
> Such a timer could also check memory usage
> simply by checking the length of the Alchemy ByteArray.
You may also check amount of memory, allocated by Lua GC:
http://www.lua.org/manual/5.1/manual.html#pdf-collectgarbage
http://www.lua.org/manual/5.1/manual.html#lua_gc
Alchemy's ByteArray should be more safe though -- since user might
somehow get access to some memory-heavy lightuserdata (a pointer,
which counts as pointer size by GC, but points to huge foreign object
in memory).
>> I'm actually interested in adding built-in sandboxing support to
>> Lua Alchemy, so I may help you here.
> Absolutely, if I can help with testing let me know!
Thanks. Sandboxing is actually an "on-demand" feature for Lua Alchemy,
so it is not a very high priority task (not a 0.3 one anyway). Sorry
for not being clear.
However, like I said, I'm interested in adding this feature, and if
you'll realize that to get it working you'll need any feature
implemented inside Lua Alchemy itself (like, for example, exposing
lua_gc to AS3 code), feel free to ask.
In return, we're open for contributions Lua Alchemy usage experience
and/or actual code. ;-)
HTH,
Alexander.
> I meant if it's not used by lua-alchemy in the course of executing
> code. (If that is somehow a stupid notion, please forget I ever
> mentioned it. :)
No, it is not a stupid notion. In fact, you're right, we planned to
use flyield() in as3.filegetcontents(). There are some problems with
that in so far:
http://tinyurl.com/bns7ey
http://tinyurl.com/c4m4dt
>> Thanks. Sandboxing is actually an "on-demand" feature for Lua
>> Alchemy, so it is not a very high priority task (not a 0.3 one
>> anyway). Sorry for not being clear.
> Perhaps I'm overlooking something, but I don't really see any need for
> sandboxing features on the lua-alchemy level. As I pointed out and you
> confirmed, resource limitations easily be enforced by AS3 and Lua
> itself has solid, mature sandboxing. So adding any feature in between
> would probably be for convenience only, perhaps even convenience at
> the expense of stability/security. Or what kind of features do you
> have in mind?
Lua Alchemy, as it is now, does not provide access to lua_State to AS3
user code. That means that all almost all you want to do with Lua, you
have to do in plain Lua. It is likely that some things you'll need for
sandboxing are better be done with Lua C API. If you need any such
thing -- feature requests are welcome.
>> In return, we're open for contributions Lua Alchemy usage
>> experience and/or actual code. ;-)
> Absolutely!
Thank you!
> The current version of the software uses a very basic
> custom scripting language, so right now I'm evaluating various
> options. Lua-alchemy is one, AS3eval (http://eval.hurlant.com/) is
> another. And finally we could simply stick with the custom language
> and extend it. Lua is looking very good right now, so if we do go with
> it, you'll definitely see me posting some code as I move along (which
> may be quite slowly, aiming for an open beta in June 09).
My opinion is highly biased, but I'll recommend you to use Lua.
Lua is mature, brilliantly designed, blazingly fast dynamic language.
I still have to see a better designed dynamic language that would be
so well balanced while being easy to use for both "system" and
business logic levels of programming.
Looking forward for any feedback on Lua Alchemy experience,
Alexander.