2011-07-15 14 views
9

Estoy trabajando en una aplicación web para enseñar conceptos de programación. Las páginas web tienen algo de texto sobre un concepto de programación, luego permiten que el usuario ingrese el código de JavaScript en una ventana del editor de texto para intentar responder un problema de programación. Cuando el usuario hace clic en "enviar", analizo el texto que han tipeado para ver si han resuelto el problema. Por ejemplo, les pido que "escriban una función llamada f que agrega tres a su argumento".¿Cómo puedo "evaluar" de forma segura el código de usuario en una página web?

Aquí es lo que estoy haciendo para analizar el texto del usuario:

  1. Run JSLint en el texto con los ajustes estrictos, en particular, sin asumir funciones del navegador o de la consola.
  2. Si hay algún error, muestre los errores y deténgase.
  3. eval(usertext);
  4. Pasa por las condiciones para pasar la tarea, eval(condition). Una condición de ejemplo es "f(1)===4". Las condiciones provienen de fuentes confiables.
  5. Mostrar condiciones de aprobación/falla.

Mis preguntas: ¿esto es lo suficientemente bueno para evitar problemas de seguridad? ¿Qué más puedo hacer para ser paranoico? ¿Hay una mejor manera de hacer lo que quiero?

En caso de que sea relevante, mi aplicación está en Google App Engine con el back-end de Python, usa JQuery, tiene cuentas de usuario individuales.

+0

Me pregunto si jsfiddle tiene alguna fuente/notas disponibles ... Estoy seguro de que en algún momento todo se reduce a que el sitio no sea vulnerable a XSS o similar.(XSS * permitiría que otra persona * proporcione un enlace al código evaluado en dicha página que luego puede "ejecutarse como" el usuario que realmente vio el enlace.) –

+0

Tengo que decir cuando uso JSLint para escanear mi JS para Problemas antes de comprimir Intento y deshabilito todas las características que puedo que simplemente representan las preferencias del autor y no un problema de código, luego ignoro el 90% de lo que dice y busco los puntos y comas que faltan. Si yo fuera tú, pensaría en cuánto disfrutarán los usuarios al leer los "errores" que encuentra JSLint. – tomfumb

+0

Ese es un buen punto, agregaré una opción para desactivar las comprobaciones "estilísticas". Pero quiero que el valor predeterminado sea estricto, parte del objetivo del proyecto es enseñar programación limpia de JavaScript. –

Respuesta

11

Por lo que puedo decir si está evaluando la entrada de un usuario solo para ellos, esto no es un problema de seguridad. Solo si se evalúa su entrada para otros usuarios de tiene un problema.

La evaluación de la entrada de un usuario no es peor que la visualización de la fuente, mirando los encabezados HTTP, utilizando Firebug para inspeccionar objetos JavaScript, etc. Ya tienen acceso a todo.

Dicho esto, si usted necesita para proteger su código, echa un vistazo a Google Caja http://code.google.com/p/google-caja/

+0

Ese es un buen punto. Si tienes Firebug, puedes evaluar lo que quieras. –

+1

Estoy de acuerdo aquí. No es un problema de seguridad para un usuario el poder manipular su propio navegador. Hay muchas maneras de hacerlo (Firebug, GreaseMonkey, copiar el origen y editarlo, etc.). Solo se convierte en un problema de seguridad si algún otro usuario puede ejecutar el código que no es de confianza en un entorno que pertenece a un usuario diferente al que lo creó sin saber qué podría hacer. – jfriend00

+0

Este es en realidad un muy buen punto. +1 – AlienWebguy

2

Esta es una pregunta capciosa. No hay una forma segura de eval() código de usuario en su sitio web.

+0

Sí, pero considere jsfiddle: ¿cómo se puede hacer "con medidas aceptables"? –

1

No se puede hacer. Los navegadores no ofrecen API a las páginas web para restringir qué tipo de código se puede ejecutar dentro de un contexto determinado.

Sin embargo, eso podría no importar. Si no utiliza ninguna cookie en su sitio web, la ejecución de Javascript arbitrario puede no ser un problema. Después de todo, si no hay un concepto de autenticación, entonces no hay problema con las solicitudes de falsificación. Además, si puede confirmar que el usuario significa para ejecutar el script que envió, entonces también debe estar protegido de los atacantes, por ejemplo, si solo ejecuta script escrito en la página y nunca script enviado a través de GET o POST datos, o si incluye algún tipo de token único con esas solicitudes para confirmar que la solicitud se originó en su sitio web.

Aún así, la respuesta a la pregunta core es que prácticamente no se puede hacer y que la entrada del usuario nunca se puede confiar. Lo siento:/

+0

Hay un concepto de autenticación, hay cuentas de usuario de Google. No sé cómo se implementan en GAE, pero supongo que las cookies almacenan una clave compartida de sesión o algo así. ¿Puedes explicar un poco más acerca de cómo distinguir entre los scripts escritos y las solicitudes GET POST? ¿Cómo puedo distinguir? –

+0

@Nathan: si el usuario escribe la secuencia de comandos en la página, es seguro ejecutarla, ya que sabemos que el usuario debe enviarla. Sin embargo, si el código proviene de datos GET o POST, entonces un usuario malintencionado puede engañar a otro usuario para que envíe esa solicitud y ejecutar esa secuencia de comandos. (Para GET, es fácil con un enlace. Para POST, un formulario de envío automático no es mucho más difícil). Por lo tanto, esas solicitudes no deberían permitirse a menos que pueda estar seguro de que provienen de su sitio, es decir, los formularios de su sitio. necesidad de incluir datos que un usuario malintencionado no podría tener. Busque la falsificación de solicitudes entre sitios y proporcione a los usuarios un token secreto. – Matchu

Cuestiones relacionadas