Archivos del Mes para Febrero, 2009

La paradoja de la máquina virtual y el interprete

Nota: durante todo el artículo se habla de máquina virtual de proceso, es decir, por ejemplo, la de Java, no de sistema, por ejemplo, VirtualBox.

Hace tiempo, estaba hablando con un amigo, y hablando hablando, se de pronto nos surgió una paradoja, que nos dejó de piedra…

Todo empezó cuando uno de los dos (no recuerdo cual) dijo que no era lo mismo una máquina virtual, que un interprete, y el otro, le contestó: claro que no, joder, eso es de informática básica, por dios.

Pero se hizo el silencio, ambos estábamos buscando rápidamente en nuestra cabeza una diferencia clave, una diferencia demoledora entre máquina virtual e interprete, pero no dábamos con ella, dimos con algunas, evidentemente, pero todas, nos dimos cuenta enseguida, o bien eran diferencias entre implementaciones concretas, por ejemplo, entre la VM de Java y el interprete de PHP, o bien eran diferencias filosóficas, en plan: la VM está pensada para ser…

Tras un rato de silencio, uno de los dijo:

¿Y cual es la diferencia técnica de base, entre una máquina virtual, y un interprete?

La pregunta sonaba de los mas absurdo, ambos sabíamos perfectamente lo que es un compilador, un pre-compilador, etc, vaya, no era un problema de falta de conocimientos en ese ámbito, pero notábamos que algo fallaba…que no dábamos con esa diferencia de base, que diferencia cosas que todo informático, sabe que son como la noche y el día.

Tras pensarlo un rato, yo dije: está claro! La máquina virtual ejecuta código medio, mientras que el interprete procesa código de alto nivel. Es decir, uno procesa código de bajo nivel, y otro de alto nivel. Pero mi amigo enseguida desmontó mi teoría hablando de Javascript.

Los interpretes de javascript, por como funcionan, son llamados máquinas virtual, por ejemplo:

http://code.google.com/p/v8/

Se puede leer claramente como google se refiere a su V8 como VM (virtual machine).

Bueno, entonces si ambos pueden procesar el mismo tipo de código, que diferencia hay?

Tras pensar un rato, mi colega dijo: la VM está pensada para abstraer al programa del hardware, y yo contesté: y PHP no? y perl no? Es exactamente lo mismo.

Durante mucho rato, fueron surgiendo ideas e ideas, pero todas, eran diferencias filosóficas, diferencias entre cierto interprete, y cierta VM…pero nunca algo genérico, aplicable a cualquier VM.

Al llegar a casa, fui a wikipedia, a sentir como si volviese a estudiar informática de nuevo, y abrí la siguiente página en el navegador:

http://en.wikipedia.org/wiki/Virtual_machine#Process_virtual_machines

Y leo la siguiente frase, muy interesante: Process VMs are implemented using an interpreter;

Según la wikipedia, lo que sucede es que una VM utiliza internamente un interprete, es decir, una VM es un interprete, y algo mas, veamos que mas:

A process VM, sometimes called an application virtual machine, runs as a normal application inside an OS and supports a single process

Eso, se puede aplicar al interprete de Python, de perl, etc.

It is created when that process is started and destroyed when it exits.

Vale, igual que el interprete de python o php.

Its purpose is to provide a platform-independent programming environment that abstracts away details of the underlying hardware or operating system, and allows a program to execute in the same way on any platform.

Vale, como TCL, por ejemplo, que es un interprete. O cualquier otro interprete, vaya.

performance comparable to compiled programming languages is achieved by the use of just-in-time compilation.

Vale, tal como hace python, no? los famosos .pyc

Después de todo esto, al final llegamos a la siguiente conclusión: no existe una diferencia técnica entre máquina virtual de proceso e interprete, es una diferencia de concepto, es decir, quien hace una VM, tiene una forma de pensar, y quien hace un interprete, otra, y eso, se refleja en el resultado final, pero como conceptos base, no encontramos diferencia.

Aprovechando una charla con un developer de mono, mi colega le preguntó sobre esta paradoja, que parece algo evidente, pero que no conseguimos resolver, y no nos dejaba vivir, el developer, tras pensarlo un buen rato, nos dijo que la diferencia era en como finaliza un interprete, y como finaliza una máquina virtual, al finalizar, la máquina virtual puede no finalizar (a diferencia de lo que nos había dicho wikipedia) y el interprete debe finalizar.

Pero esto no nos convencía, es algo mas de implementación que de concepto, y podría existir un interprete que no finalizase, sino esperase mas scripts para ejecutar.

Al final, comido por las dudas, viví agobiado un tiempo, hasta que un día, di con la respuesta, y era bastante tonta, ciertamente.

Una vez con la respuesta, se me ocurrió una idea, llevar la pregunta al meneame (craso error):

http://meneame.net/notame/jcarlosn/119061

Y un par de usuarios, tal como me esperaba, ante lo evidente que parece la pregunta en primera instancia, me tacharon de ignorante, de no saber lo que era un compilador, etc etc…pero a la hora de dar una respuesta, me dieron la siguiente: Una máquina virtual ejecuta código intermedio, no entendible por el ser humano, mientras que un interprete ejecuta código de alto nivel, entendible por el ser humano.

Esta respuesta se cae por su propio peso, en primer lugar, eso depende de la implementación de VM, por ejemplo, la V8 de google, incluida en chrome, ejecuta código javascript, de alto nivel, en segundo lugar, para procesar el MSIL, por poner un ejemplo, la plataforma .net, utiliza un interprete, eso es evidente.

Al final, después de mucho dolor de cabeza e intrigas, tengo una bonita paradoja que me sirve para diferenciar a informáticos que van de superdioses, de la gente que realmente sabe.

Siempre que he hecho está pregunta a un desarrollador de algún proyecto de software libre, se lo ha pensado, a contestado, y alguno, ha dado en el clavo, mientras que siempre (al menos de momento) que se la he hecho a un estudiante o joven informático español, se ha réido de mi, me ha descalificado, se ha reído de la pregunta, pero finalmente, no la ha contestado.

De hecho, otro dato curioso de la paradoja, es que de momento el 100% de los preguntados estudiantes de informática españoles, responden asumiendo que hablamos de la VM de Java, enhorabuena a los de marketing de SUN. :)

Por cierto, una nota para que nadie se ofenda, no quiero decir que ningún estudiante de informática español pueda contestar esto, sino que yo he tenido una mala experiencia :)

Tuenti solventa todos los agujeros de seguridad comunicados

No suelo hacer entradas cortas y sin contenido (sin experimentos, bugs, o cosas raras), pero creo que la historia del bug de tuenti, merece explicar el desenlace.

tuenti

Continuando con el anterior post, sobre un agujero de seguridad en tuenti, durante estos últimos días he estado en contacto con Ícaro Moyano, director de comunicación de tuenti, el cual ha mostrado mucho interés y ha sido muy proactivo y comunicativo para solventar cuanto antes los errores de seguridad.

Aparte del problema con los amigos, existían otros agujeros de seguridad de tipo XSS, en la gestión de eventos de la web, permitiendo crear un evento, y al mandar la invitación a un tercero, robarle la cookie y con ello, su sesión.

A diferencia de lo que suele pasar al contactar con ciertas compañías, toda la gente de tuenti ha sido muy amable y comunicativa, y se ha preocupado muchísimo por solventar todos los errores cuanto antes.

En contraposición con esto, se está creando una falsa imagen negativa en la red, sobre la seguridad en tuenti, ya que mucha gente empieza a pensar que dicha red social es insegura, solo por que se le encuentran problemas de seguridad. La realidad es que todos los servicios 2.0 tienen agujeros de seguridad, absolutamente todos, lo que hace seguros a unos, e inseguros a otros, es como actúan ante ellos, y en el caso de tuenti, ha sido impecable.

Ahora tuenti es un poquito mas seguro :)

Agujero de seguridad en Tuenti

Normalmente no frecuento las webs sociales, como Tuenti, o Facebook, sin embargo, hoy me ha dado por cotillear un poco a unos amigos, que tienen tuenti.

El tuenti es entretenido, tanto que me he puesto a cotillear y no he parado, sin embargo, ha llegado un momento, que para continuar mi cotilleo, me hubiese sido útil poder ver la lista de amigos de alguien que no es mi amigo, sin embargo, en teoría eso no se puede…

Me he puesto a investigar, y he comprobado que para ver la lista de amigos de un amigo tuyo, utilizas un link tal como:

http://www.tuenti.com/#m=amigos&uid=X

Donde X es el uid (el número identificador único de tu amigo).

Lo interesante, es que si en lugar del número uid de nuestro amigo, ponemos cualquier otro, podemos ver también la lista de sus amigos.

Parecía que ya lo tenía todo, que ya podía ver quien era amigo de fulanito, pese a que fulanito no me tenía como amigo a mi…sin embargo, es muy incomodo ir mirando el uid de fulanito para ver quien es su amigo y quien no…por ello, me decidí a crear un script greasemonkey que agrega un botón ‘Ver amigos sus amigos’ al lado del botón ‘Agregar amigo’ de un contacto que no es tu amigo.

El script greasemonkey es este:

// ==UserScript==
// @name           tuentihacks
// @namespace      tuenti
// @include        http://www.tuenti.com/*
// ==/UserScript==

var column = document.getElementById(‘column-550′);
var els = column.getElementsByTagName(‘a’);

myRe = /addFriend\(([0-9]+)/g;
for (var i = 0; i < els.length; i++) {
var clk = els[i].getAttribute(‘onClick’);
var arr = myRe.exec(clk);
if(arr) {
var id = arr[1];
var btn = document.createElement(‘a’);
btn.setAttribute(‘href’,'http://www.tuenti.com/#m=amigos&uid=’+id);
btn.className = ‘blue’;
btn.innerHTML = ‘ | Ver sus amigos’;
els[i].parentNode.appendChild(btn);
}
}

Un screenshot en funcionamiento:

imagen-42

Realmente, tuenti tiene mas bugs que he encontrado, pero son mas serios y esos los comunicaré por privado a sus administradores, he decidido publicar este, por que no es ningún drama, y es gracioso :)

Actualización: La gente de tuentiadictos ha tenido la amabilidad de colgar el script por separado para que sea mas fácil instalarlo en greasemonkey, podéis instalarlo desde aquí.

Vulnerabilidad XSS en google image labeler (no explotable)

Bueno, tras mucho tiempo sin actualizar el blog, por motivos personales… hoy he decidido volver a escribir por aquí.

Han pasado muchas cosas desde que escribí la última entrada del blog…me he comprado una blackberry storm, un macbook 5.1…etc, ya jugaré con ellos y publicaré como siempre, mis descubrimientos.

El caso es que hoy me ha pasado algo curioso, estaba buscando una imagen en google image search, cuando veo que debajo hay un link a una nueva herramienta de google, llamada google image labeler, donde te pones un nick, y tagueas imágenes, consiguiendo puntos.

Esta herramienta es sencilla, se basa en que como hay muchas personas usando google image labeler, te muestran una imagen a ti, y una imagen a otra persona, ambos sugerís tags sobre la imagen, y los que coincidan, se aceptan como tags válidos, de esta forma, no se pueden meter tags basura, ya que para que te acepten un tag sobre una imagen, otro usuario escogido al azar, debe sugerir el mismo tag que tu.

La idea es muy buena, estuve jugando un rato y agregué tags a unas 200 imágenes sin darme cuenta, es entretenido.

El caso es que en la pantalla principal, cuando entras, te pide que introduzcas un nick para jugar, en ese campo, si introduces código html, por ejemplo:

“><hr>

Dicho código se ejecuta en el contexto de la página, produciendo lo que conocemos como XSS (Cross Site Scripting). Además, esto solo sucede si al introducir el nick, pulsamos intro (enter), si pulsamos sobre el botón ‘Ok’, los caracteres especiales se filtran, sin que se produzca el XSS.

xss en google image labeler

XSS en google image labeler

Es un bug curioso, que se filtre si pulsas Ok, pero no cuando pulsas intro en la caja de texto, seguramente no es explotable (o yo no he sabido ver la manera…), pero tiene su gracia ver una página con un XSS, y en la barra de direcciones, google.com.

Como vemos, nadie está a salvo de los despistes, en este caso parece ser que es inofensivo, pero este tipo de despistes (filtrar en un sitio si, en otro no) son muy muy peligrosos cuando desarrollamos.