Flash Player, sockets y políticas de seguridad

El pasado miércoles 9 de abril Adobe liberó una actualización de su Flash Player numerada como 9.0.124. Esta noticia pasaría completamente desapercibida si no fuese por las implicaciones que tiene. De hecho no entiendo como una actualización con los cambios que conlleva se ha numerado como una actualización menor y no se le ha dado más importancia.

El cambio fundamental de esta nueva versión radica en el modelo seguridad de la máquina virtual Flash al de acceder a sockets remotos y al utilizar headers HTTP. Recordemos que la opción de abrir sockets binarios y conectarse a ellos permitiendo aplicaciones bajo cualquier protocolo apareció en julio de 2006 junto a la versión 9 de Flash Player. Hasta ahora el modelo de seguridad de sockets era el mismo que para cualquier llamada remota bajo Flash, el famoso crossdomain.xml. Según esto, para acceder a cualquier archivo que no resida bajo el mismo host que sirve el swf que hace la llamada, el host servidor debe autorizar a la maquina virtual Flash la carga de ese archivo a través de ese crossdomain.xml, si no existe o no se autoriza el acceso, no se podrá acceder. Este es, por tanto, un archivo de políticas de seguridad y decide quién puede conectarse con Flash a tu servidor. A mi, personalmente, siempre me ha parecido algo ridículo, es como si para cargar un archivo de cualquier host desde tu navegador tuviesen que autorizártelo, pero siempre habrá quien encuentre ventajas en la seguridad. Si el archivo está publicado en Internet se supone que ya estas autorizado a leerlo, ¿para qué complicar más todo el proceso requiriendo más políticas de seguridad?. Y vaya si se complica…

Hasta ahora los sockets se trataban como archivos en lo que a políticas de seguridad se refiere, es decir, el crossdomain.xml del host al que conectábamos nos autorizaba el acceso igual que con cualquier llamada http. Si tienes una aplicación que utiliza sockets y actualizas a Flash Player 9.0.124 verás que ahora no te funciona, te salta una excepción de seguridad. Los chicos de Adobe se han inventado un sistema de políticas de seguridad exclusivo para sockets e independiente de las llamadas http.

Desde Adobe se han currado una ayuda/explicación de 7 páginas. Ninguna pega a no ser porque llegas al final de la lectura con la pregunta, vale, pero ¿qué tengo que hacer para que funcione? Es decir, mucha lectura pero poca, muy poca ayuda, da la impresión de que repiten lo mismo en todas las páginas sin aclarar nada.

La solución es sencilla a la par que curiosa y complicada para muchas aplicaciones. Debes crear una pequeña aplicación que, bajo el puerto 843 por defecto (aunque puedes usar otros puertos), debe responder a las peticiones de acceso con el crossdomain.xml. La mayoría de la gente ha entendido que debes tener tu servidor web a la escucha en el puerto 843 y devolver el crossomain.xml desde allí (como veis no está clara la documentación), pero NO es eso, no es una llamada HTTP la que te va a hacer el swf para pedir autorización. Veámoslo con un ejemplo práctico. Supongamos que fuese una solicitud HTTP, a grosso modo haríamos:

telnet www.tuhost.com 843
GET /crossdomain.xml HTP/1.0
HTTP/1.x 200 OK
Date: Tue, 15 Apr 2008 17:24:26 GMT
Server: Apache
Last-Modified: Thu, 28 Oct 2004 21:57:25 GMT
Content-Length: 128
Content-Type: text/xml

<xml version="1.0" encoding="UTF-8">.....</xml>

El xml final sería nuestro crossdomain.xml. Esto sería lo mismo que si cargamos el crossdomain.xml desde el puerto 80. Vale, pues esto es lo que NO va a hacer el swf, por tanto, no sirve. Esto es lo que va a hacer:

telnet www.tuhost.com 843
<policy-file-request/>
<xml version="1.0" encoding="UTF-8">.....</xml>

La diferencia es evidente, en el segundo caso, al contectar con el servidor simplemente le decimos <policy-file-request/> y nos debe devolver el xml del crossdomain.xml. No es el protocolo HTTP, es uno inventado que sólo responde a una petición.

El puerto no tiene porqué ser el 843, puedes modificarlo, pero Adobe pretende que 843 sea el estándar y, de hecho, está solicitando su homologación con el IANA.

Desde Adobe incluso se han puesto cachondos y te dicen que lo ideal es modificar tu aplicación en el servidor para que acepte la llamada <policy-file-request/> y responda con el XML, así no necesitarás una aplicación adicional. Pues nada chicos, a modificar todos los servidores smtp, pop, irc (nuestro caso), ftp… para que acepten la llamada. ¡Qué ridículo!

Como soy un tío enrollado os paso la solución completa. En esta URL tenéis un ejemplo de servidor en TCL/TK que funciona a la perfección y no consume recursos. Configura el puerto y la ruta al crossdomain.xml y a funcionar. Recuerda que si el puerto es inferior al 1024 deberá ser un usuario privilegiado quién ejecute la aplicación, deberías, entonces, enjaularla (chroot) para evitar posibles puertas. En realidad lo que hacemos es responder con el crossdomain.xml a cualquier petición que nos hagan, sea la correcta o no, ¿qué mas da? No vamos a hacer absolutamente nada más con ese puerto. Tendréis que preocuparos también de que se quede residente como demonio en vuestro servidor y, además, habrá que comprobar periódicamente que sigue a la escucha. Para esto recomiendo hacer un script que haga llamadas reales y espere el código XML necesario, comprobar simplemente con un netstat que el servidor ocupa el puerto no nos salvará de que el servidor se quede zombie. Por supuesto no olvides abrir tu firewall a ese puerto.

Actualización.
Acabo de terminar el artículo y a través de flexcoders me llega este enlace, mucho más claro y sencillo que la ayuda inicial. Ah! y con ejemplos de servidores en Perl y Python. En líneas generals viene a contar lo mismo que acabo de contar yo :P.

2 comentarios en “Flash Player, sockets y políticas de seguridad

  1. Muchas gracias por este post, ha sido de verdadera utilidad. Siempre he intentado no tener que llegar a este punto de crear un crossdomain.xml, pero al final ha sido inevitable.
    La recopilación de todos los links es genial. Lo guardaré como oro en paño porque seguro que más adelante tendré que volver a mirarlo.

    Un saludo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *