Hace unos días analicé el performance de este blog con la herramienta gratuita más completa que conozco, https://www.webpagetest.org
Obtuve una F de Fracaso en seguridad. ¿Qué he hecho tan mal? La respuesta es simple, a este blog le faltaban 3 HTTP headers básicos de seguridad.

¿Qué es una cabecera HTTP?
Los mensajes HTTP es el medio a través del que se intercambian datos entre el servidor y el navegador.
Cada petición HTTP tiene dos componentes: el contenido, por ejemplo un fragmento de código HTML, y la cabecera (header en inglés), que contiene información adicional sobre ese contenido y cómo debe ser tratado.
Los servidores se pueden configurar para enviar ciertas cabeceras HTTP en cada petición.
Puedes ver esto abriendo la consola del navegador, en la pestaña red (network), seleccionando cualquiera de las peticiones que aparecerán una vez que refresques la página.

Ejemplos de cabeceras HTTP habituales:
Content-type: indica el formato del documento descargado
Server: el tipo de servidor HTTP empleado.
Age: Tiempo que ha estado el recurso almacenado en un proxy cache (en segundos).
Cache-control: Se usa para indicar al navegador qué objetos cachear y durante cuánto tiempo.
Los 3 HTTP headers que han mejorado el security score de este blog, pasando de F a B:
1. X-Frame-Options sameorigin
X-Frame-Option (XFO), impide que alguien pueda incluir tu página en otro sitio a través de un iframe. Esto dificulta ataques de tipo clickjacking, en los que se muestra contenido de otra web de forma engañosa para “secuestrar” clicks.
Un ejemplo típico clickjacking es un botón like de Facebook en el que se camufla el click a otra web, ya sea para abrir un anuncio, descargar contenido malicioso, o alguna otra acción malintencionada.
El valor “X-Frame-Options sameorigin” permite mostrar el contenido en un iframe sólo si es en la propia web, tu página no podrá ser cargada a través de un iframe desde ningún otro dominio. Facebook utiliza la opción más restrictiva, “X-Frame-Options DENY” para impedir que su contenido se muestre en n iframe, aunque sea dentro de Facebook.com
2. X-Content-Type-Options nosniff
Para explicar la utilidad de “X-Content-Type-Options”, es necesario saber que en la comunicación entre el servidor y el navegador se utilizan los MIME types, Multipurpose Internet Mail Extension, para indicar al navegador el formato del recurso que se está descargando y cómo debe interpretarlo.
Los MIME types aparecen en la cabecera content-type que vimos anteriormente. Por ejemplo, el content type de una hoja de estilos es text/css, mientras que un archivo JavaScript debería ser application/javascript
El header X-Content-Type-Options nosniff, informa al navegador que no debe cambiar el content-type que aparece en el documento.
Esto evita que se puedan transformar archivos no-ejecutables en ejecutables. Por ejemplo, si nuestro navegador se descarga un script, pero este script tiene un content type incorrecto, text/html, el navegador ejecutará el script igualmente, porque detecta que es un ejecutable. El header “X-Content-Type-Options nosniff” impide que esto suceda. Fuerza al navegador a obedecer el content-type indicado, por lo que en ese caso bloqueará el script al no coincidir con el MIME text/html.
Como curiosidad, la palabra nosniff viene de que el navegador utiliza pistas para detectar el formato cuando el contenido del recurso es incorrecto o no está indicado. Se fija en pistas como el número de bytes del archivo. Nosniff, traducido al castellano sería “No olfatear”, indica al navegador que no debe buscar esas pistas. Aquí puedes leer sobre el algoritmo utilizado para descifrar el tipo de archivo: https://mimesniff.spec.whatwg.org/#mime-type-sniffing-algorithm
3. Strict-Transport-Security «max-age=31536000; includeSubdomains; «;
La cabecera Strict-Transport-Security, también conocida como HSTS, informa al navegador que los recursos deben ser enviados a través de HTTPS. Esto ayuda a mitigar ataques de tipo MITM (man in the middle), ya que el navegador fuerza la encriptación SSL de las conexiones en caso de haber visitado la web anteriormente.
max-age=31536000 informa el tiempo en segundos que el navegador debe recordar que tiene que acceder al site a través de HTTPS.
includeSubdomains es un parámetro opcional para indicar que la directiva aplica también a los subdominios.
Si te ha interesado este artículo, el siguiente paso es analizar la seguridad de tus headers: https://securityheaders.com/ y aplicar cambios si fuese necesario.
Con sólo estos 3 cambios, ha cambiado el security score a B, espero seguir mejorando hasta llegar al sobresaliente y poder contarlo en un segundo post.
