esquema://dirección:puerto/ruta/al/recurso?consulta#fragmento
La recomendación es usar POST sobre GET para ejecutar acciones que cambian datos, ¿pero por qué?
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.
Cada respuesta del servidor viene con asociado un código de respuesta, que se agrupan en los siguientes segmentos:
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.
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.
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'
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;'
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'
<%
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();
}
%>
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.
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.
<?php
header('Location: '.$_GET['url']);
?>
http://e.com/p.php?url=http://e.com/z.php
HTTP/1.1 200 OK
Location: http://e.com/z.php
[...]
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.
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.
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
[...]
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].
Los navegadores que usamos a diario han implementado algunas medidas de seguridad tales como:
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:
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.
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].
Existen algunas técnicas para relajar las restricciones de SOP, como:
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.
Para profundizar más en este tema, se recomiendan los siguientes recursos:
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.
Cabecera añadida para prevenir que Internet Explorer realice "MIME-sniffing" sobre las respuestas recibidas.
X-Content-Type-Options: nosniff
<?php header('Content-Type: application/pdf'); ?>
<html>
<p>Hello world</p>
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.
Para evitar este tipo de vulnerabilidades, es aconsejable usar la cabecera X-Content-Type-Options.
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
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
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)
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)
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
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.