2011-03-01 12 views
7

Estoy jugando con la idea de construir un intérprete en línea C#, un poco como Codepad. Ahora bien, hay problemas de seguridad obvias: los buclesC# en línea problemas de seguridad del intérprete

  • Infinito
  • System.Diagnostics.Process.Start
  • casi todo el espacio de nombres System.IO

Mi conocimiento de C# no es exactamente insignificante, pero estoy seguro de que hay muchas cosas que saben mucho más sobre eso, más las cosas en las que no pensé. ¿De qué serías cuidadoso?

Algunas precisiones, planeo ejecutar esto en un pequeño VPS Linux usando Mono.

+0

que conocer la naturaleza de la cuestión probablemente no es muy StackExchange-ish, por lo que figura Voy a aceptar la respuesta más completa. –

+0

¿No tiene esencialmente el mismo mecanismo de seguridad que Java? –

+0

¿Terminaste tu intérprete? – Shimmy

Respuesta

4

Utilice la capacidad Compiler as service de Mono. Se puede compilar en una DLL compatible con Silverlight (perfil de cliente), y has been ya, que puede checkout. Eso debería abordar algunas de sus preocupaciones sobre IO.

+0

+1: Parece el camino a seguir, ya que Microsoft ya ha hecho el trabajo de definir los riesgos de seguridad dentro de la DLL. Después de eso, solo tiene que centrarse en los problemas de uso incorrecto (por ejemplo, las personas que usan su servicio para realizar ataques de DOS). – StriplingWarrior

+0

¿No requeriría esto que el cliente tenga instalado Silverlight? – DotnetDude

+0

@DotNetDude: en el ejemplo de Runcs, silvelight es obligatorio, pero si estaba ejecutando la DLL Mono.CSharp en un servidor, es solo el servidor el que requiere la instalación de .NET. (El perfil del Cliente solo requiere .NET, no Silverlight). –

1

Reflexión viene a la mente, ya que podría pasar de GetType() a Assembly a cualquier cosa que desee.

+1

IMO, la reflexión es exactamente lo que desea evitar, ya que le permite ejecutar (potencialmente) código arbitrario, en lugar de un subconjunto restringido que desea aplicar por razones de seguridad. –

1

En realidad, el código de usuario puede hacer cualquier cosa. sería difícil abordar casos especiales. En mi opinión, la mejor manera de hacerlo es:

a) create sandbox appdomain con permiso de ejecución solamente. Esto garantiza muchas cosas como la incapacidad de meterse con el sistema de archivos o realizar llamadas a bibliotecas nativas.

b) cree un nuevo proceso e inicie su dominio de aplicación en él.

Luego monitoree el proceso de manera ajustada para la memoria y el consumo de la CPU. Si algo sale mal, mátalo. Tenga en cuenta que es el proceso que puede matar, no appdomain. Con appdomain puedes intentar descargarlo, pero si el código malicioso se ejecuta en la cláusula finally, entonces no funcionaría.

todavía hay algunos (que yo conozca) problemas con esto:

  • tener cuidado de donde se coloca ensamblados compilados por el usuario. En realidad, incluso en el código de usuario del dominio de aplicación menos privilegiado podrá cargar ensamblajes que están en el mismo directorio y ejecutarlos.
  • He mencionado que debe controlar el proceso estrechamente. Código (ejecutándose en la cláusula finally) que engendra hilos en bucle infinito, donde cada hilo hace la misma captura de memoria extremadamente rápido (en mis observaciones). si un atacante decide hacer dos ataques con dicho código, quién sabe qué sucede :) Tal vez una forma de aprovechar esto es iniciar el proceso del usuario con baja prioridad para que los hilos de supervisión tengan la posibilidad de una supervisión adecuada en un sistema cargado.

Así que, en general, hay un riesgo de todos modos. Yo estaba jugando con esta idea también y aquí está el resultado actual: rundotnet

1

Echa un vistazo a este enlace y podrás aprender algo sobre intérpretes C# en línea, probar algunas cosas y leer las excepciones de salida para ver cómo Ellos lo hicieron.

http://rextester.com/NWDF62346

Cuestiones relacionadas