2008-11-28 13 views
6

Estaba trabajando en una solución de cadena Lua localizable, cuando se me ocurrió este truco, el problema es que no sé cómo evitar ser pirateado :) Así que me preguntaba si alguien ha hecho algo similar y o sabe cómo protegerse de este tipo de ataque. (En el código de usuario)¿Hay alguna forma de evitar este problema de seguridad en Lua?

Dado que podemos hacer esto:

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

Puede ser pirateado así:

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) 

¿Alguna idea?

+1

No es necesario utilizar el metatabla de cadena; es simplemente la cadena de tabla global. Entonces, usando string.upper = function ... los usuarios finales aún podrán cambiar la función. – jpjacobs

Respuesta

8

Primero y antes que nada ejecute el código que no es de confianza solo en el entorno de espacio aislado, como lo dijeron otros carteles. A excepción de cargar fragmentos de bytecode, Lua permite cubrir todos los demás problemas de sandboxing. (Y los problemas del bytecode se arreglan rápidamente como se descubrió.)

Vea Lua Live Demo para ver un ejemplo de sandboxing.Las fuentes están disponibles here.

Su problema específico con metatablas se resuelve mediante el establecimiento de un campo __metatable:

Si establece un campo __metatable en el metatabla, getmetatable devolverá el valor de este campo, mientras que setmetatable generará un error .

- Roberto Ierusalimschy, programación en Lua 1ª edición, 13.3 - Library-Defined Metamethods

Por ejemplo:

> 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]: ? 

Por lo tanto, todo lo que tiene que hacer es:

getmetatable("").__metatable = true 
+0

__metatable es lo que yo estaba buscando, ¡había olvidado esto! –

6

Si tu hacker tiene la capacidad de agregar código, y necesitas permitir que ese código llame a cosas como os.exit, entonces de todos modos estás fuera de suerte.

Sin embargo, puede restringir las funciones que su código puede llamar. Depende de lo que aún desee que el código de usuario pueda hacer. Consulte el documento para setfenv y google para "lua sandbox"

+0

Me refiero, por supuesto, a que el módulo no está disponible para los usuarios, pero lo usé para el factor de impacto en mi código. De todos modos, gracias por la idea de la caja de arena, no había pensado en googlear eso. –

2

No estoy seguro de por qué tiene un problema, ya que probablemente ya conozca las cajas de arena: puede eliminar las funciones peligrosas como io.exit, y puede garantizar que se invaliden las funciones son solo aquellas en la tabla global del usuario, es decir. las funciones Lua utilizadas internamente por su aplicación permanecerán intactas.
En cualquier caso, si el hacker puede llamar a os.exit directamente, el hecho de que pueda dispararse en el pie al sobrecargar una función inocente que usará más adelante es su problema.
Además, es un problema solo si ejecuta funciones de usuario en su servidor, por ejemplo: si el hacker destruye su sistema, ¡ese es su problema!
Ahora, también existe la cuestión de distribuir código peligroso: depende de usted restringir el poder de los scripts de usuario. Después de todo, eso es lo que hacen los navegadores con JavaScript.

+0

El problema está anulando string.upper, no directamente utilizando os.exit. Pero no estoy seguro si sandboxing protegerá directamente contra la anulación, pero ahora que lo menciona también debería ocultar las funciones get/setmetatable del entorno del usuario. –

0

No tengo solución (no utilizo Lua, solo me interesa desde lejos), pero lo que buscas es lo que se llama "caja de arena". Google por Lua sandbox, encontré algunas páginas aparentemente interesantes de esa manera. Por ejemplo: http://lua-users.org/wiki/SandBoxes.

2

Este problema de seguridad se ilustra típicamente con esta frase, dijo por Ford prefecto en los brillantes libros La guía del autoestopista galáctico: It rather involved being on the other side of this airtight hatchway

Mi capacidad de escribir código no se puede decir que sea una garantía vulnerabilidad, y si no puede controlar su código, que es su problema de seguridad, no lo que ese código puede hacer.

Hay toneladas y toneladas de cosas que puede hacer si solo puede hacer que la máquina ejecute parte de su código. La seguridad es evitar obtener el código allí en primer lugar. Todo después de eso es solo daño colateral.

La forma de evitar ser atacado por ese problema es evitar que se introduzca un código desconocido en la aplicación.

+0

+1 para la verificación de la realidad; sin embargo, mi objetivo es permitir que se ejecute algún código de usuario. Pero sí, tienes razón. Necesito repensar mi problema aquí. –

+0

. El enfoque de caja de arena que otros mencionan es desconocido para mí, así que parece que tienes una manera de limitar esta habilidad en este caso. –

1

No veo la posibilidad de redefinir upper como el problema. Poder ver os.exit es el problema.

Según lo sugerido por otros, cree un entorno de espacio aislado para sus scripts. Cada script puede obtener uno nuevo; entonces una persona puede redefinir la parte superior o algo por el estilo, y lo único que arruinarán es lo suyo.

Crear estados Lua es tan rápido y fácil, esto no causará ningún problema.

Otra cosa de la que puede estar seguro es de los bucles eternos. Hacer un "perro guardián" que mata un guión después de, digamos, 10000 instrucciones toma alrededor de 10 líneas de código C. Puedo enviarte una muestra si lo necesitas.

Cuestiones relacionadas