Cunas de seguridad: CSRF

imagen

A pesar de que en la última lista publicada de vulnerabilidades de los ataques CSRF Top 10 2017 de OWASP se clasifican como "Eliminados, pero no olvidados", decidimos que no sería superfluo recordar una vez más cómo defenderse de los ataques CSRF, confiando en aquellos las mismas reglas provistas por OWASP.

Uso de token CSRF

El uso de un token (métodos sin estado y con estado) es el método de protección principal y más popular. El token debe ser único para cada sesión de usuario, generado por un generador de números pseudoaleatorios criptográficamente robusto. OWASP también recomienda usar los algoritmos AES256-GCM y SHA256 / 512 para el cifrado cuando se usa HMAC.

Existen varios enfoques para trabajar con tokens: token de sincronizador, patrón de token basado en cifrado, token basado en HMAC

Token de sincronizador

El uso del enfoque de token sincronizador (método con estado completo) significa enviar un token en cada solicitud, lo que implica algunos cambios en el lado del servidor. Si el token no es válido, el servidor rechaza la solicitud.
Al enviar una solicitud al servidor, se recomienda agregar un token a los parámetros de la solicitud en lugar de al encabezado. Sin embargo, si inserta un token en el encabezado de la solicitud, asegúrese de que no esté registrado en el servidor. El token recibido se puede almacenar en el lado del cliente en un campo oculto:

<form action="/post.php" method="post"> <input type="hidden" name="CSRFToken" value="l5824xNMAYFesBxing975yR8HPJlHZ"> ... </form> 


en los encabezados:

 POST /page HTTP/1.1 Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36 Content-Type: application/json Host: example.com X-CSRF-TOKEN: l5824xNMAYFesBxing975yR8HPJlHZ 


o en cookies

 POST /page HTTP/1.1 Host: example.com Set-Cookie: CSRFToken=l5824xNMAYFesBxing975yR8HPJlHZ; Content-Type: application/x-www-form-urlencoded 


OWASP recomienda almacenar el token en los encabezados, explicando que incluso si el token está abierto o caducado, el atacante aún no podrá falsificar la solicitud, debido a los navegadores.

Además, para aumentar el nivel de seguridad del método propuesto, se propone generar un nombre de parámetro de token aleatorio y / o el token en sí para cada solicitud. Con este enfoque, el tiempo durante el cual el atacante puede usar el token robado es mínimo. Sin embargo, esto puede conducir a problemas de usabilidad. Por ejemplo, hacer clic en el botón "Atrás" puede provocar el envío de un token no válido al servidor, que estaba contenido en la página anterior.

No se recomienda enviar un token utilizando una solicitud GET, ya que con este enfoque se puede revelar el token: en el historial del navegador, archivos de registro, encabezados de referencia.

Token basado en cifrado

Este enfoque no tiene estado, porque utiliza cifrado / descifrado para validar el token y, por lo tanto, no requiere almacenamiento del token en el lado del servidor.

El servidor genera un token que consta de un identificador de sesión y una marca de tiempo (para evitar un ataque de repetición). Para el cifrado, se recomienda utilizar el algoritmo de cifrado AES256 en el modo de cifrado de bloque GSM / GSM-SIV. Se desaconseja usar el modo ECB. El token cifrado por el servidor se devuelve al cliente de la misma manera que en el caso de "Token de sincronizador" en el campo de formulario oculto o en el encabezado / parámetro de respuesta. Al recibir el token, el servidor debe descifrarlo, luego verificar el identificador de sesión y también verificar la marca de tiempo con la hora actual y asegurarse de que no exceda la vida útil establecida del token.
Si la verificación del identificador de sesión es exitosa, pero el mapa de tiempo no lo es, entonces la solicitud puede considerarse válida. En todos los demás casos, se recomienda rechazar la solicitud y registrarla para comprender mejor cómo responder a dichas solicitudes.

Token basado en HMAC

Tampoco requiere almacenamiento de tokens, el principio de funcionamiento es similar al Token basado en cifrado, excepto que en lugar de cifrar el token, se utiliza la función HMAC (código de autenticación de mensaje basado en hash) para generar el token (se recomienda usar SHA256 o un algoritmo más fuerte). En este caso, el token es el resultado de la función HMAC del identificador de sesión de usuario + marca de tiempo.

Automatización de tokens

El principal problema para contrarrestar los ataques CSRF es que los desarrolladores a menudo simplemente se olvidan de agregar funcionalidad para trabajar con tokens. Para evitar tales problemas, vale la pena automatizar este proceso:

• escriba un contenedor que agregue automáticamente un token a las solicitudes a través de la etiqueta del formulario o cuando use ajax. Por ejemplo, Spring Security adopta un enfoque similar cada vez que se usa la etiqueta <form: form>.

• escriba un enlace que intercepte el tráfico y agregue tokens a todos los recursos vulnerables. Dado que es bastante difícil analizar qué solicitud está realizando el cambio de estado, que requiere un token, se recomienda incluir tokens en todas las respuestas POST, pero vale la pena considerar el costo del rendimiento

• agrega automáticamente un token al representar una página. CSRF Guard utiliza este enfoque: los tokens se agregan a todos los atributos href y src, campos ocultos y en todas sus formas

Antes de intentar escribir su propio sistema de generación automática de tokens, se recomienda aclarar si el marco que utiliza tiene la capacidad de proporcionar protección contra ataques CSRF de forma predeterminada. Por ejemplo, el mismo marco de Django implementa protección contra CSRF.


Iniciar sesión CSRF

Usando CSRF en el formulario de inicio de sesión, un atacante puede iniciar sesión,
disfrazado de víctima. Tales vulnerabilidades fueron enfrentadas por gigantes como PayPal y Google.
Puede lidiar con CSRF en el formulario de inicio de sesión creando sesiones previas que se crean antes de que el usuario se autentique e incluyendo tokens en el formulario de inicio de sesión.


Galleta samesita

SameSite Cookie es un atributo descrito en RFC6265bis cuyo propósito es contrarrestar los ataques CSRF. Funciona de la siguiente manera. Uno de los métodos de protección es verificar el origen y los encabezados de referencia, mediante los cuales puede comprender de dónde proviene la solicitud, pero este enfoque requiere la implementación de un mecanismo de verificación. Usando el atributo SameSite, restringimos el envío de cookies con una solicitud de recursos extraños. Este atributo tiene varios valores posibles: estricto, laxo y ninguno.
El uso del valor estricto significa que el navegador no enviará cookies de ninguna fuente que no coincida con el nombre de dominio del recurso actual.
El valor lax hace posible no bloquear las cookies de recursos externos, cuya transición se realizó de forma segura, utilizando el protocolo HTTPS. Lax logra un equilibrio entre usabilidad y seguridad.

Establecer un atributo es bastante simple:

 Set-Cookie: JSESSIONID=xxxxx; SameSite=Strict Set-Cookie: JSESSIONID=xxxxx; SameSite=Lax 


Al momento de escribir, el soporte para el atributo por parte de los navegadores se ve así:

imagen


Es importante recordar que este atributo debe usarse como una medida adicional de protección, y no como una forma de hacerlo sin usar el token CSRF.

Comprobación de encabezados

Como se mencionó anteriormente, uno de los métodos de protección es verificar los valores de referencia y origen del encabezado de la solicitud.
La esencia de esta verificación es verificar los valores de los encabezados en el lado del servidor. Si coinciden con el recurso, la solicitud se considera correcta, de lo contrario, se rechaza. Si falta el encabezado Origin, debe asegurarse de que el valor de referencia coincida con el recurso actual. OWASP recomienda rechazar las solicitudes que no contengan encabezados de origen o referencia. También puede registrar todas esas solicitudes para analizarlas más adelante y decidir cómo tratarlas.

Sin embargo, las cosas se complican si su aplicación está detrás de un servidor proxy, ya que la URL en el encabezado será diferente. En este caso, hay varias opciones:
• Configure su aplicación para que siempre sepa el origen de la solicitud. El problema con este enfoque es establecer el valor correcto si su aplicación se implementa en varios entornos (por ejemplo, desarrollo, control de calidad, producción), lo que conduce a un problema de soporte
• use el encabezado Host. Este encabezado le permitirá determinar el origen de la solicitud, independientemente del entorno.
• use el encabezado X-Fordered-Host, cuyo propósito es almacenar los encabezados originales recibidos por el servidor proxy

Todos los métodos descritos solo funcionan cuando los encabezados de origen y referencia están presentes. Pero hay casos en que faltan estos encabezados. Aquí hay algunos casos en los que estos encabezados no están incluidos en la solicitud:
• IE 11 no incluye el encabezado Origin para sitios confiables. Queda por depender solo del encabezado Referer.
• en el caso de una redirección, Origin no está incluido en la solicitud, ya que se cree que puede contener información confidencial que no debe enviarse a otra fuente
• El encabezado de origen está habilitado para todas las solicitudes entre sitios, pero la mayoría de los navegadores lo agregan solo para solicitudes POST / DELETE / PUT

Como regla, una pequeña cantidad de tráfico cae en las categorías descritas, pero a menudo no desea perder ni siquiera esta pequeña parte de usuarios, por lo tanto, se considera válido solicitar con un valor nulo para origen / referencia o con un valor correspondiente a la lista de dominios de confianza.

Cookie de envío doble

Este enfoque es bastante simple de implementar y no requiere almacenamiento del token en el lado del servidor (sin estado). La esencia del método es enviar el token en el parámetro de solicitud y en las cookies por parte del usuario. Cada solicitud que requiere un cambio de estado, verificamos el valor del token en las cookies y en la solicitud. Si la verificación del identificador de sesión es exitosa, pero el mapa de tiempo no lo es, entonces la solicitud puede considerarse válida

Source: https://habr.com/ru/post/476880/


All Articles