Clase 02: Introducción al protocolo HTTP y al navegador.

Taller de Seguridad Web

Claudio Salazar (csalazar spect cl)



Sky - Beige - Simple - Serif - Night - Default

Agenda

  • Introducción al protocolo HTTP.
  • Las reglas en los navegadores.
  • Cabeceras enfocadas en seguridad.

Introducción al protocolo HTTP

Libro de referencia: The Tangled Web

Hypertext Transfer Protocol (HTTP)

  • Es un protocolo cliente-servidor sin estado que solventa esa deficiencia mediante el uso de cookies.
  • Se accede a los recursos mediante una URL (Uniform Resource Locator).

Uniform Resource Locator (URL)

esquema://dirección:puerto/ruta/al/recurso?consulta#fragmento
  • Múltiples parámetros son concatenados en la consulta mediante &.
  • El string correspondiente a fragmento no es enviado al servidor.
  • Una URL es enviada junto a un método de petición y un conjunto de cabeceras.

Métodos de petición HTTP

  • GET: método para recuperar información.
  • POST: método para acciones que cambian información.
  • Otros métodos: TRACE, PUT, HEAD, DELETE, OPTIONS, CONNECT.

Uso adecuado de los métodos de petición HTTP

La recomendación es usar POST sobre GET para ejecutar acciones que cambian datos, ¿pero por qué?

  • Logs en proxies y servidor web.
  • Información en la cabecera Referer.
  • Petición guardada en el historial del navegador.
  • Si bien no es una medida de seguridad, GET posibilita escenarios que no se dan con POST.

Cabeceras HTTP

Hay una gran cantidad de cabeceras, tanto de petición como de respuesta, que guían el comportamiento del navegador y la aplicación. No son visibles a simple vista y representan un buen nicho de posibles vulnerabilidades a descubrir.

Para mayor referencia, consultar este listado.

Códigos de respuesta HTTP

Cada respuesta del servidor viene con asociado un código de respuesta, que se agrupan en los siguientes segmentos:

  • 100's :: Información.
  • 200's :: Éxito.
  • 300's :: Redirección.
  • 400's :: Error del cliente.
  • 500's :: Error del servidor.

Otro uso de los códigos de respuesta HTTP

Todas las aplicaciones manejan de distinta forma los errores. Algunas los muestran, otras los ocultan, y también algunas lo manejan con diferentes código de respuesta.

Si se prueba un vector de ataque, códigos de éxito pueden ser el caso positivo, en cambio códigos de redirección o error interno podrían indicar que nuestro vector tiene errores en la síntaxis.

Codificaciones en aplicaciones web

Diversos mecanismos para codificar carácteres son usados por las aplicaciones web, tanto para transportar como desplegar carácteres. A continuación se revisan los más comunes.

Codificación URL

Codifica cualquier carácter problemático para ser transportado seguramente sobre HTTP y que puede tener un significado especial en la URL.

Formato: '%' + valor hexadecimal del carácter.


hex('&') = 0x26  ->  url_encoding('&') = '%26'
hex('&') = 0x26  ->  double_url_encoding('&') = '%2526'

Codificación HTML

Codifica carácteres problemáticos para ser incorporados seguramente en documentos HTML.

Formato: '&' + valor decimal del carácter o entidad + ';' (sin espacio)


ent('"') = 'quot'  ->  html_encoding('"') = '& quot;'
dec('"') = 34  ->  html_encoding('"') = '& #34;'

Codificación Unicode

Codifica cualquier carácter según su code point. Varía si corresponde a UTF-16 o UTF-8.

Formato UTF-16: '%u' + code-point del carácter.

code-point('é') = \u00e9  ->  unicode_encoding('é') = '%u00e9'

Formato UTF-8: '%' + code-point del carácter.

code-point('©') = c2 a9  ->  unicode_encoding('©') = '%c2%a9'

Demo

Análisis de peticiones HTTP

Ejemplo de caso real [1]


    <%
    if (Request.Headers['X-Forwarded-For']){
      string ip = Request.Headers['X-Forwarded-For'];
      Request.Headers['Remote_Addr'] = ip;
    }

    if (Request.Headers['Remote_Addr'] == '127.0.0.1'){
      show_admin();
    }
    %>
    

Escenario de vulnerabilidad

Se puede realizar una petición normal y añadir la cabecera 'X-Forwarded-For' con el valor '127.0.0.1', con lo cual lograríamos acceder a la interfaz de administración.

Buena práctica

La gran mayoría de las cabeceras HTTP pueden ser alteradas por un atacante y aún así generar una petición válida.

No se puede confiar en el contenido de las cabeceras HTTP.

Ejemplo de caso real - PHP 5.1.2 [1]


      <?php
      header('Location: '.$_GET['url']);
      ?>
    

Escenario normal

http://e.com/p.php?url=http://e.com/z.php

    HTTP/1.1 200 OK
    Location: http://e.com/z.php
    [...]
    

Escenario de vulnerabilidad

Sabiendo que las cabeceras HTTP están separadas por saltos de línea, podríamos pasar un argumento con saltos de línea para insertar cabeceras de nuestra elección.

Análisis de la vulnerabilidad

Los carácteres "\r\n" (%0d%0a en codificación URL) permiten insertar una nueva línea si es que son interpretados correctamente, lo que permitiría añadir cabeceras arbitrariamente.

La medida de seguridad en PHP sólo verificaba el carácter "\n", sin embargo en navegadores como Chrome o IE "\r" es interpretado como un separador válido de nueva línea.

Explotación de la vulnerabilidad

http://e.com/p.php?url=http://e.com/z.php%0DSet-Cookie:+NAME=foo

    HTTP/1.1 200 OK
    Location: http://e.com/z.php
    Set-Cookie: NAME=foo
    [...]
    

Evitando estos casos

Este bug fue corregido, pero se puede dar en otros lenguajes o frameworks. La solución es aplicar codificación URL a los argumentos pasados a las cabeceras [1].

  • Frameworks como Django es inmune a este tipo de vulnerabilidades.
  • En Rails se han aplicado medidas en redirect_to.
  • Recientemente parchado en Node.js [2].

Las reglas en los navegadores

Los navegadores

Los navegadores que usamos a diario han implementado algunas medidas de seguridad tales como:


  • Sandbox de procesos
  • Protectores de ataques XSS.
  • Protección contra phishing.
  • Notificaciones sobre certificados SSL, recursos no seguros, etc.

Los navegadores

Cada navegador tiene su propio parser HTML, el cual puede o no seguir estándares (que es lo apropiado). Esto da lugar a una serie de situaciones:


  • La explotación de vulnerabilidades puede diferir entre navegadores.
  • Vulnerabilidades podría existir en algunos navegadores, mientras que en otros no.
  • Para constatar la existencia de una vulnerabilidad es suficiente con un vector funcionando exitosamente en un navegador.

Document Object Model (DOM) [1]

Es la representación en memoria del documento (página) tal cual la interpretó el parser HTML del navegador. Su nodo de acceso es a través de la variable 'document', presente en Javascript.


El uso inadecuado del DOM propicia la aparición de vulnerabilidades que serán revisadas en las próximas clases.

Same-Origin Policy (SOP) [1]

Permite el acceso al DOM de un sitio A desde un sitio B si ellos comparten el mismo esquema, nombre de host y puerto. En caso contrario, no es posible tal acceso.


También aplica a la API XMLHttpRequest [2].

Relajando SOP

Existen algunas técnicas para relajar las restricciones de SOP, como:

  • El atributo document.domain.
  • JSONP [1] y Cross-Origin Resource Sharing[2].
  • Cross-document messaging [3].
  • Las políticas de cada plugin.

Plugins

Existen múltiples tecnologías como Flash, Java, SilverLight y otros plugins que son ampliamente soportados por los navegadores actuales, pero también presentan nuevos nichos de vulnerabilidades.


  • Fallas propias del código de la aplicación.
  • Vulnerabilidades en la máquina virtual del plugin.
  • Posibilidad de descompilar/desensamblar los ficheros binarios para inspeccionar el código.

Aspectos técnicos a fondo

Para profundizar más en este tema, se recomiendan los siguientes recursos:

Cabeceras enfocadas en seguridad

A continuación, se revisan una serie de cabeceras de respuesta que se han creado para disminuir la superficie de ataque en el navegador cuando un usuario interactúa con una aplicación vulnerable.

X-Content-Type-Options

Cabecera añadida para prevenir que Internet Explorer realice "MIME-sniffing" sobre las respuestas recibidas.


X-Content-Type-Options: nosniff

Ejemplo de caso real [1]


    <?php header('Content-Type: application/pdf'); ?>
    <html>
    <p>Hello world</p>
    

Escenario de vulnerabilidad

Si usamos IE8, de acuerdo al algoritmo para determinar el tipo MIME de la página, se ejecutará el HTML siendo que la cabecera 'Content-Type' establecía que el contenido fuera tratado como PDF.

Buena práctica

Para evitar este tipo de vulnerabilidades, es aconsejable usar la cabecera X-Content-Type-Options.

  • Otra medida podría ser añadir la cabecera 'Content-disposition: attachment' si es adecuado para la situación.
  • Otros navegadores no han optado por este enfoque sino basarse en las especificaciones. [1]

X-XSS-Protection

Cabecera que activa o desactiva el filtro XSS, una característica incorporada en Internet Explorer.


X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block

X-Frame-Options

Indica al navegador si la página puede ser desplegada o no dentro de un i?frame. Es útil para evitar ataques del tipo ClickJacking [1].


X-Frame-Options: deny
X-Frame-Options: same-origin

HTTP Strict Transport Security

Informa al navegador que nunca debería cargar la versión HTTP del sitio, y convertir todos los intentos de conexión de HTTP a HTTPS. Esto permite evitar ataques man-in-the-middle [1].


Strict-Transport-Security (Firefox y basados en Webkit)

Content Security Policy

Permite crear una lista blanca de fuentes de contenido confiable, e instruye al navegador a solo ejecutar o desplegar recursos de esas fuentes [1] [2] .


X-Content-Security-Policy (Firefox)
X-WebKit-CSP (Basados en Webkit)
Content-Security-Policy (Consenso)

Cookies

Existen algunas opciones que se pueden añadir a la declaración de cookies para prevenir su acceso desde Javascript o desde recursos que no están bajo SSL. [1]


Set-Cookie: name=value; HttpOnly
Set-Cookie: name=value; secure

Ayuda para desarrolladores

Los frameworks actuales proveen ayuda para implementar estas medidas, ya sea en forma de guía o mediante paquetes de software.

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.