deshabilitar pólitica X-Frame-Options en PhantonJS / QtWebKit
El encabezado opcional “X-Frame-Options” del Response HTTP, nos permite poder definir una regla de renderización (aceptar o denegar) al momento de cargar una página en un elemento frame/iframe, esto es muy útil para evitar ataques del tipo Clickjacking o si deseamos que nadie nos pueda incrustar una página en un iframe. Siempre y cuando el browser sea “amigable” y respecte dicha regla.
En el obscuro xD mundo del web scraping/harvest puede ser muy útil desactivar está directiva, sin embargo, esto requiere modificar el motor de renderizado , en definitiva, hacer un browser customizado.
Lamentablemente, no podemos desactivar la pólitica “X-Frame-Options” en el browser de línea de comando phantonjs, sin embargo, si lo podemos modificar para desactivar dicha política . Esto se puede lograr modificando el archivo “Source/WebCore/loader/FrameLoader.cpp” de QtWebKit, específicamente, en el método FrameLoader::shouldInterruptLoadForXFrameOptions, el cual es el encargado de interrumpir la carga de una página según las reglas de la pólitica X-Frame-Options. Por lo tanto, solo debemos retornar false para ignorar la regla siempre.
Los pasos serían los siguientes.
1- Obtener una copia del repositorio de phantonjs
git clone git://github.com/ariya/phantomjs.git cd phantomjs git checkout 2.1.1 git submodule init git submodule update
2.- Modificar el archivo src/qtwebkit/Source/WebCore/loader/FrameLoader.cpp
Buscamos la función shouldInterruptLoadForXFrameOptions y la modificamos para que siempre devuelve false.
bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, const KURL& url, unsigned long requestIdentifier) { return false; }
3.- Compilamos phantonjs
python build.py
Y luego de varios minutos, tenemos una version modificada de phantonjs en la carpeta bin.
Probamos nuestro mod
He preprado un sencillo test que contiene una página html con un iframe con google.com (sitio que tiene la política x-frame-options que no permite ser incrustado en un iframe) junto a un script phantonjs que realiza la captura de la imagen, esto lo pueden encontrar en https://github.com/deerme/phantomjs/tree/master/test/x-frame-options.
cd test/x-frame-options/ #Versión instalada de phantonjs phantomjs screenshot.js test-iframe.html phantomjs-without-mod.png #Versión modificada ../../bin/phantomjs screenshot.js test-iframe.html phantomjs-with-mod.png
Prueba con phantonjs 1.9.8
Prueba con phantomjs 2.1.1 modificado
¿Para que nos sirve? Agregando la regla –web-security=no al ejecutable de phantonjs junto a esta modificación, podemos cargar cualquier url en un iframe en particular, inclusive, ejecutar código js en dicho iframe, como para automatizar el rellenado de un form, etc. Algo muy útil en el mundo del web harvest .
He realizado un fork de la rama principal de phantonjs a mi repositorio de github con este cambio, lo pueden clonar desde aquí https://github.com/deerme/phantomjs.