Fortificación de un recurso al estilo ninja para Magento

Hace poco me llegó un trabajo peculiar. Debo proteger ciertos recursos de un servidor Apache pero sin tocar código existente ni añadir código a Magento (que es el gestor e-commerce que usa quien me hizo llegar este trabajo).

El tema se presenta de la siguiente forma

  • Servidor con Apache instalado.
  • Corriendo una versión de Magento al cual no le puedo tocar el código fuente.
  • Sistema sin autenticación de usuarios, por tanto no hay credenciales.
  • Es preferible que el sistema de contraseña no redirija a otra página distinta.
  • El trabajo debe estar listo lo antes posible (horas).

Con unos requisitos tan ajustados hay que echar mano de la imaginación para poder encontrar una solución que se ajuste a las necesidades de lo que me han pedido, así que me puse manos a la obra y aquí voy a comentar un poco por encima el proceso que seguí.

Algunos de los requisitos derivados de la lista superior son los siguientes:

  • No puedo usar ninguna librería javascript (como jQuery).
  • No puedo redirigir a otra página, por tanto he de usar AJAX.

Lo primero de todo es que si no puedo añadir (ni modificar) código a Magento debo ingeniármelas para poder inyectar código sin necesidad de modificar los ficheros fuente. La única forma que se me ocurrió para hacer esto es en el editor de texto que tiene Magento, cuando el usuario va a publicar una nueva entrada/producto. Vale, encontramos una manera de inyectar código "facilmente", a partir de ahora necesitamos crear un sencillo sistema de autenticación en base a contraseñas y proteger los links que enlazan a los recursos a proteger. Este sistema se tiene que llevar a cabo a través de AJAX para mantenernos en la misma página y no redirigir al cliente a otra distinta.

Para esto, a parte de inyectar código (html y javascript) en los enlaces mediante el editor de Magento necesito una comprobación por parte del servidor de que la contraseña es correcta, si la contraseña es correcta entonces el servidor devuelve la URL de descarga y mediante javascript se hace una redirección al recurso.

Aquí está el código que hay que inyectar en cada enlace del editor de Magento

Siento que el código aparezca en una sola línea pero así es como lo programé para que no diese fallos.

Aquí está el fichero php que comprueba que todo es correcto

Llegados a este punto podemos pensar que tenemos lo recursos protegidos.

  • Nos pide contraseña para los recursos.
  • Una vez se ha comprobado que la contraseña es correcta nos devuelve la URL.

La única forma de obtener los recursos sería saber cual es la URL que devuelve el fichero validate.php cuando se ha introducido una contraseña correctamente. Y llegados aquí no es tan difícil averiguar la URL del recurso, si accedemos a las herramientas de desarrollador de un navegador (en mi caso firefox) mediante Ctrl+Shift+C e intentamos acceder al recurso con una contraseña correcta nos encontraremos con lo siguiente:

URL del recurso

Nota: en la demostración de más abajo al ser ficheros txt y no tener ninguna directiva en mi servidor serán mostrados directamente en el navegador, así que para ver la URL de descarga no es necesario hacer lo que comento arriba.

Si pasamos esta URL a nuestros amigos serán capaces de acceder al recurso protegido. Para solucionar esto basta con añadir un fichero .htaccess a la carpeta Download (en mi caso la carpeta se llama así) con el siguiente contenido.

Lo que hacemos es prohibir todo acceso cuya página anterior sea nula o pertenezca a un dominio distinto del nuestro. Esto nos permitirá que si cogemos el enlace y lo pegamos directamente en la barra de direcciones del navegador la página anterior sea vacía y nos devuelva el siguiente texto:

Forbidden

You don't have permission to access /poc/mag/Download/Resource1.txt on this server.
Apache/2.4.9 (Ubuntu) Server at angelluis.zapto.org Port 80

Lo de "página anterior" tiene una explicación técnica y es que el navegador en cada petición envía la cabecera HTTP_REFERER indicando la página desde la cual se refiere.

Por supuesto este método se puede saltar fácilmente modificando la petición que se realiza y añadiendo la cabecera HTTP_REFERER correcta, en este caso el posible atacante se saltaría la medida de "seguridad" de .htaccess. Pero con el tiempo y las limitaciones que me han impuesto poco más se puede hacer. Otra forma distinta de haber configurado el .htaccess podría haber sido mediante mod_rewrite de Apache de la siguiente forma

Lo ideal sería haber hecho una validación completa por parte del servidor y que sea el servidor el que te entregue el recurso mediante la función readfile de php y no que el servidor te devuelva la URL del recurso. Quedaría algo parecido a lo siguiente

Nota: Esta opción no se ha llevado a cabo porque las peticiones por AJAX en principio solo admiten datos de texto plano y no datos binarios por tanto en principio no es posible descargar un fichero por AJAX.

Y ya puestos tener un poco más de tiempo para examinar como está programado Magento para modificarlo y poder usar algún widget más apropiado para la contraseña (con ocultación de caracteres cada vez que introduces un carácter) y otra reforma sería implementar un sistema de autenticación de usuarios y que la contraseña dependa tanto del usuario como del recurso que se quiere descargar.

Por supuesto, este sistema es válido para todo aquél sitio que permita introducir etiquetas HTML y javascript, y este blog es un ejemplo de ello.

Aquí dejo la demostración (contraseñas 1234 y 4321 respectivamente)

How to stream video with VLC and HTML5

The previous week I was researching how to stream video with VLC to webpage.

So, in order to do that I need launch VLC with de following command (on Linux) in order to capture the screen, transcode it and finally send to localhost port 8181.

vlc screen:// --screen-left=67 --screen-top=53 --screen-width=800 --screen-height=600 --screen-fps=30 --sout '#transcode{vcodec=theo,vb=800,scale=0.25,width=800,height=600,acodec=none}:http{mux=ogg,dst=:8181/}' --ttl=3

 

In the other hand, I need to built a webpage in order to visualize video stream. To do that I used video tag of html5. It can visualize video adding <video>. Inside <video> I should indicate video source, instead of indicate a source file I indicated http://localhost:8181/ as source.

Now, if I open http://localhost:8181/ in my browser I can see my screen in the webpage.

If I want to visualize a video from video capture card instead of screen:// I should use dshow:// in the vlc command.

Bittorrent Sync and how to address mapping on D-Link DSR-500N Router

Right now, I am configuting a Bittorrent Sync network in order to decide if my company should use this service or not.

Bittorrent Sync is similar to Dropbox in the sense that the information will be replicated on each approved computer, the difference is that information doesn't upload to the cloud, it only will be stored in each computer that knows a Secret Key.

I have installed the client in my work computer (Windows) and in a industrial computer that works thanks to Linux. The installation of windows client is very simple, download the installer and run it. The installation of linux client is a bit more complicated but not much. Donwload the tar.gz file for your arch (i386 in my case) then extract files (tar xvzf btsync_i386.tar.gz) and finally run btsync (./btsync).

The windows client has a desktop gui in order to manage your shared folder with the windows system but linux client haven't got it. Linux client has a web gui that you can access it by enter the following URL in your browser:

http://localhost:8888/gui/

Inside my network everybody can access it by enter the following URL in its browser:

http://YOUR_LOCAL_IP:8888/gui/

The problem is that I am behind a DSR-500N router (Only I am behind that router, the rest of worker are connect directly with the company network) so I need map the router IP with the Linux client IP. In order to do that I do the following steps:

Step 1: Click on the Advanced tab and select Firewall Settings > Firewall Rules.

Step 2: Click Add.

Step 3: Create Rule:

From Zone: Insecure (WAN)
To Zone: Secure (LAN)
Service: HTTP
Action: Always Allow

Internal IP address: IP of local machine hosting service
Enable Port Forwarding: unchecked
Translate Port Numbers: Leave Unchecked
External IP address: Dedicated WAN

Step 4: Click Save Settings

And now the rest of worker can access to the web gui of Linux client.