Is there anyway to avoid this security issue in Lua?

I was just working on a localizable Lua string solution, when I came up with this hack, problem is I don't know how to avoid getting hacked by it :) So I was wondering if anyone, has done something similar and or knows how to protect from this kind of attack. (in user code)

Since we can do this:

=("foo"):upper() -->output: FOO

It can be hacked like this:

getmetatable("foo").__index.upper = function() print("bye bye sucker");os.exit() end
=("foo"):upper() -->output: bye bye sucker (application quits)
-- or this way
=string.upper("bar") -->output: bye bye sucker (application quits)

Any ideas?


First and foremost execute untrusted code in sandboxed environment only – as it was said by other posters. Except for loading bytecode chunks, Lua allows all other sandboxing issues to be covered. (And bytecode chunk problems get fixed promptly as discovered.)

See Lua Live Demo for an example of sandboxing. Sources are available here.

Your specific problem with metatables is solved by setting a __metatable field:

If you set a __metatable field in the metatable, getmetatable will return the value of this field, whereas setmetatable will raise an error.

– Roberto Ierusalimschy, Programming in Lua 1st edition, 13.3 - Library-Defined Metamethods

For example:

> mt = { __metatable = true }                                                   
> t = {}
> setmetatable(t, mt)
> setmetatable(t, mt)
stdin:1: cannot change a protected metatable
stack traceback:
 [C]: in function 'setmetatable'
 stdin:1: in main chunk
 [C]: ? 

So, all you have to do is:

getmetatable("").__metatable = true

If your hacker has the ability to add code, and you need to allow that code to call things like os.exit, then you're pretty much out of luck anyway.

You can restrict the functions that their code can call, though. It depends on what you still want user code to be able to do. See the doc for setfenv and google for "lua sandbox"

I am not sure why you have an issue, since you probably already know about sandboxes: you can remove dangerous functions like io.exit, and you can ensure the overridden functions are only those in the global table of the user, ie. the Lua functions used internally by your application will remain intact. In any case, if the hacker can call os.exit directly, the fact he can shoot himself in the foot by supercharging an innocent function he will use later is his problem. Beside, it is a problem only if you run user functions on your server, for example: if the hacker destroys his system, again, that's his problem! Now, there is also the issue of distributing dangerous code: it is up to you to restrict the power of user scripts. After all, that's what browsers do with JavaScript.

This security problem is typically illustrated with this sentence, said by Ford Prefect in the brilliant books The Hitchhiker's Guide to the Galaxy: It rather involved being on the other side of this airtight hatchway

My ability to write code cannot be said to be a security vulnerability, and if you can't control your code, that is your security problem, not what that code can do.

There are tons and tons of things you can do if you can just get the machine to execute some of your code. The security is to avoid getting the code in there in the first place. Everything after that is just collateral damage.

The way to avoid being hacked by that problem is to avoid getting unknown code into your application.

I don't see the possibility to redefine upper as the problem. Being able to see os.exit is the problem.

As suggested by others, make a sandboxed environment for your scripts. Each script can get a new one; then a person can redefine upper or anything like that, and all they'll screw up is their own thing.

Creating Lua states is so fast and easy, this won't cause any problems.

Another thing you might beware of is eternal loops. Making a 'watchdog' that kills a script after, say, 10000 instructions takes about 10 lines of C code. I can send you sample if you need.

I have no solution (I don't use Lua, I'm just interested in it from afar), but what you're after is called a "sandbox". Google for Lua sandbox, I found a few seemingly interesting pages that way. For example:

Need Your Help

Eclipse - What is exactly a Builder?

eclipse-cdt builder

I don't understand what is exactly a builder in CDT, and what is the relationship with the "C/C++ Build" content.

Ruby tutorial Ch9 Exercise #9 - Don't Allow Admin to Delete Themselves

ruby-on-rails-3 tdd

I am a total newbie to Ruby and Rails which is why I am going through the Rails Tutorial by Michael Hartl. I am stuck on Chapter 9, Exercise #9. I have updated the def destroy code in the Users