Falsificación de solicitudes entre sitios (CSRF)

Spring proporciona soporte integral para proteger contra Falsificación de solicitudes entre sitios (CSRF). En las siguientes secciones cubriremos:

  • >¿Qué es un ataque CSRF?

  • Protección contra ataques CSRF

  • Recomendaciones sobre CSRF

¿Qué es un ataque CSRF?

La mejor manera de entender qué es CSRF es ataque, mirando un ejemplo específico.

Supongamos que el sitio web de su banco tiene un formulario que le permite transferir dinero del usuario actualmente conectado a otra cuenta bancaria. Por ejemplo, un formulario de traducción podría verse así:

Formulario de traducción

<form method="post"
      action="/transfer">
<input type="text"
       name="amount"/>
<input type="text"
       name="routingNumber"/>
<input type="text"
       name="account"/>
<input type="submit"
       value="Transfer"/>
</form>

La solicitud HTTP correspondiente podría verse así:

Transferir solicitud HTTP

POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded
amount=100.00&routingNumber=1234&account=9876

Ahora imagine que inició sesión en el sitio web de su banco y luego, sin cerrar sesión, visitó el sitio web de los atacantes. El sitio web de los atacantes contiene una página HTML con el siguiente formulario:

Formulario de transferencia de intrusos

<form method="post"
      action="https://bank.example.com/transfer">
<input type="hidden"
       name="amount"
       value="100.00"/>
<input type="hidden"
       name="routingNumber"
       value="evilsRoutingNumber"/>
<input type="hidden"
       name="account"
       value="evilsAccountNumber"/>
<input type="submit"
       value="Win Money!"/>
</form>

Te gusta ganar dinero, así que haces clic en el botón Enviar. Al hacerlo, sin querer le entregó $100 al atacante. Esto se debe a que, aunque el sitio del atacante no ve sus cookies, las cookies asociadas con su banco aún se envían junto con la solicitud.

La peor parte es que todo este proceso podría automatizarse usando JavaScript. Esto significa que ni siquiera tuvo que presionar un botón. Además, esto podría suceder con la misma facilidad al visitar un sitio auténtico que se ha convertido en víctima de XSS - ataques. ¿Cómo se puede proteger a los usuarios de este tipo de ataques?

Protección contra ataques CSRF

La razón por la que los ataques CSRF son posibles es que la solicitud HTTP del sitio de la víctima y la solicitud del sitio web del atacante son absolutamente idénticos. Esto significa que no hay forma de rechazar las solicitudes provenientes del sitio web de los atacantes y permitir solicitudes provenientes del sitio web del banco. Para protegernos contra ataques CSRF, debemos asegurarnos de que haya algo en la solicitud que el sitio del atacante no pueda transmitir para que podamos distinguir entre las dos solicitudes.

Spring proporciona dos mecanismos para protegernos contra Ataques CSRF:

  • Plantilla de token de sincronizador

  • Configuración del atributo SameSite en una cookie de sesión

Ambas opciones de seguridad requieren que los métodos seguros sean idempotentes

Los métodos seguros deben ser idempotentes

Para que funcione cualquiera de las opciones de protección CSRF, la aplicación debe garantizar que Los métodos HTTP "seguros" son idempotentes. Esto significa que las solicitudes con el método HTTP GET, HEAD, OPTIONS y TRACE no deben cambiar el estado del

Plantilla de token de sincronización

El método predominante y más completo de protección contra ataques CSRF es utilizar patrón de sincronizador de token. Esta solución es que cada solicitud HTTP requerirá que, además de nuestra cookie de sesión, un valor seguro generado aleatoriamente llamado token CSRF esté presente en la solicitud HTTP.

Una vez enviada la solicitud HTTP, el servidor debe buscar el token CSRF deseado y compararlo con el token CSRF real en la solicitud HTTP. Si los valores no coinciden, la solicitud HTTP debe rechazarse.

La clave de este trabajo es que el token CSRF real debe estar en una parte de la solicitud HTTP que no sea agregada automáticamente por el navegador. Por ejemplo, requerir que se incluya un token CSRF real en un parámetro HTTP o encabezado HTTP protegerá contra ataques CSRF. Solicitar el token CSRF real en la cookie no funcionará porque el navegador agrega automáticamente las cookies a la solicitud HTTP.

Podemos hacer que los eventos esperados sean menos estrictos y solo requerir el token CSRF real para cada solicitud HTTP. , que actualiza el estado de la aplicación. Para que esto funcione, nuestra aplicación debe garantizar que los métodos HTTP seguros sean idempotentes. Esto mejorará la usabilidad, ya que necesitamos permitir enlaces a nuestro sitio a través de enlaces desde sitios externos. Además, no necesitamos agregar un token aleatorio al método HTTP GET, ya que esto podría provocar una fuga de token.

Veamos cómo cambia nuestro ejemplo cuando utilizamos el patrón de token sincronizador. Supongamos que el token CSRF real debería estar en un parámetro HTTP denominado _csrf. El formulario de traducción en nuestra aplicación se verá así:

Formulario de token de sincronizador

<form method="post"
      action="/transfer">
<input type="hidden"
       name="_csrf"
       value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/>
<input type="text"
       name="amount"/>
<input type="text"
       name="routingNumber"/>
<input type="hidden"
       name="account"/>
<input type="submit"
       value="Transfer"/>
</form>

El formulario ahora contiene entradas ocultas con un valor de token CSRF. Los sitios externos no podrán leer el token CSRF, ya que la misma política de origen garantiza que el sitio malicioso no podrá leer la respuesta.

La solicitud HTTP correspondiente para una transferencia de dinero se verá así:

Solicitud de token de sincronizador
POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded
amount=100.00&routingNumber=1234&account= 9876&_csrf=4bfd1575-3ad1-4d21-96c7-4ef2d9f86721

Es posible que observe que la solicitud HTTP ahora contiene un _csrf parámetro con un valor aleatorio seguro. El sitio del atacante no podrá pasar el valor correcto para el parámetro _csrf (que debe pasarse explícitamente en el sitio del atacante) y la traducción fallará cuando el servidor compare el token CSRF real con el CSRF esperado, token.

Atributo SameSite

Una forma emergente de protegerse contra ataques CSRF es especificar SameSite para cookies. El servidor puede especificar el atributo SameSite al configurar una cookie para indicar que la cookie no debe enviarse cuando proviene de sitios externos.

Spring Security no controla directamente la creación de cookies de sesión, por lo que no brinda soporte para el atributo SameSite. Spring Session proporciona soporte para el atributo SameSite en aplicaciones basadas en servlet. CookieWebSessionIdResolver en Spring Framework proporciona soporte para el atributo SameSite en aplicaciones basadas en WebFlux.

Un encabezado de respuesta HTTP de ejemplo con SameSite El atributo podría verse así:

Respuesta HTTP con el atributo SameSite
Set-Cookie: JSESSIONID=randomid; Dominio=banco.ejemplo.com; Seguro; Sólo Http; SameSite=Lax

Los valores válidos para el atributo SameSite son:

  • Estricto: cuando se especifica este parámetro, cualquier solicitud proveniente de mismo sitio incluirá cookies. De lo contrario, la cookie no se incluirá en la solicitud HTTP.

  • Lax – si las cookies especificadas se envían al llegar desde mismo sitio o si la solicitud proviene de la navegación de nivel superior y el método es idempotente. De lo contrario, la cookie no se agregará a la solicitud HTTP.

Veamos cómo se puede proteger nuestro ejemplo usando el atributo SameSite. Una aplicación bancaria puede protegerse contra ataques CSRF configurando el atributo SameSite en la cookie de sesión.

Al configurar el atributo SameSite en nuestra cookie de sesión, la El navegador continuará enviando la cookie JSESSIONID con las solicitudes provenientes del sitio bancario. Sin embargo, el navegador ya no enviará una cookie JSESSIONID con una solicitud de transferencia de datos proveniente del sitio web de un atacante. Dado que la sesión ya no está incluida en la solicitud de transferencia proveniente del sitio del atacante, la aplicación estará protegida del ataque CSRF.

Hay varias consideraciones que se deben tener en cuenta al utilizar el atributo SameSite para proteger contra ataques CSRF.

Establecer el atributo SameSite en Estricto proporciona mayor seguridad, pero puede confundir a los usuarios. Considere un usuario que visita un sitio de redes sociales ubicado en social.example.com. El usuario recibe un correo electrónico a email.example.org, que contiene un enlace al sitio de red social. Si un usuario hace clic en un enlace, tiene una expectativa razonable de que será autenticado en el sitio de red social. Sin embargo, si el atributo SameSite se establece en Estricto, la cookie no se enviará y el usuario no será autenticado.

Podríamos mejorar la seguridad y usabilidad del mecanismo de protección contra ataques CSRF usando SameSite implementando gh-7537.

Otro matiz obvio: para que el SameSite El atributo protege a los usuarios, el navegador debe brindar soporte para el atributo SameSite. La mayoría de los navegadores modernos admiten el atributo SameSite . Sin embargo, es posible que los navegadores más antiguos que todavía se utilizan no proporcionen dicho soporte.

Por este motivo, generalmente se recomienda utilizar el atributo SameSite como defensa en profundidad en lugar de como único mecanismo. protección contra ataques CSRF.

Casos para usar la protección CSRF

¿Cuándo debería usar la protección CSRF? Recomendamos utilizar la protección CSRF para cualquier solicitud que pueda ser procesada por un navegador utilizado por usuarios habituales. Si está creando un servicio que será utilizado exclusivamente por clientes sin navegador, lo más probable es que necesite desactivar la protección CSRF.

Protección CSRF y formato JSON

Una pregunta común: "¿Necesita proteger las solicitudes JSON ejecutadas por javascript?". Respuesta corta: "Depende de la situación". Sin embargo, debe estar atento ya que existen vulnerabilidades CSRF que pueden afectar las solicitudes JSON. Por ejemplo, un atacante podría llevar a cabo un ataque CSRF con JSON usando el siguiente formulario:

Ataque CSRF usando el formulario JSON

<form action="https://bank.example.com/transfer" method="post" enctype="text/plain">
	<input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
	<input type="submit"
           value="Win Money!"/>
</form>

El resultado será la siguiente estructura JSON

Ataque CSRF utilizando una solicitud JSON

{ "amount": 100,
"routingNumber": "evilsRoutingNumber",
"account": "evilsAccountNumber",
"ignore_me": "=test"
}

Si la aplicación no validó el tipo de contenido, sería susceptible a este exploit. Dependiendo de la configuración, una aplicación Spring MVC que verifica el tipo de contenido aún se puede explotar actualizando el sufijo de la URL para que termine con .json, como se muestra a continuación:

Ataque CSRF usando formato JSON en Spring MVC

<form action="https://bank.example.com/transfer.json" method="post" enctype="text/plain">
	<input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value='test"}' type='hidden'>
	<input type="submit"
           value="Win Money!"/>
</form>

CSRF y aplicaciones de navegador sin estado

¿Qué pasa si mi aplicación no tiene estado? Este hecho no significa que estés perfectamente protegido. De hecho, si no se requiere que el usuario realice ninguna acción en el navegador web para una solicitud determinada, es probable que aún sea vulnerable a ataques CSRF.

Por ejemplo, considere una aplicación que usa en lugar de JSESSIONID es una cookie personalizada que contiene todo el estado que contiene. Cuando se produce un ataque CSRF, se enviará una cookie personalizada junto con la solicitud de la misma manera que la cookie JSESSIONID de nuestro ejemplo anterior. Esta aplicación será vulnerable a los ataques CSRF.

Las aplicaciones que utilizan autenticación básica también son vulnerables a los ataques CSRF. La aplicación es vulnerable porque el navegador incluirá automáticamente el nombre de usuario y la contraseña en cualquier solicitud de la misma manera que se envió la cookie JSESSIONID en nuestro ejemplo anterior.

Consideraciones de CSRF

Cuando se implementa protegerse contra ataques CSRF requiere algunas consideraciones especiales.

Iniciar sesión

Para protegerse contra falsificación de solicitud de inicio de sesión La solicitud de inicio de sesión HTTP debe estar protegida contra ataques CSRF. La protección contra solicitudes de inicio de sesión falsificadas es necesaria para evitar que un atacante lea la información confidencial de la víctima. El ataque se lleva a cabo de la siguiente manera:

  • Un usuario malintencionado inicia sesión a través de CSRF utilizando las credenciales del usuario malintencionado. Luego, la víctima se autentica como usuario malintencionado.

  • El usuario malintencionado engaña a la víctima para que visite el sitio pirateado e ingrese información confidencial.

  • La información está vinculada a la cuenta de usuario del atacante, después de lo cual puede iniciar sesión con sus credenciales y ver la información confidencial de la víctima.

Posible complicación para proteger HTTP solicitudes para iniciar sesión debido a ataques CSRF es que el usuario puede experimentar un tiempo de espera de sesión, lo que provoca que la solicitud sea rechazada. Los tiempos de espera de sesión sorprenderán a los usuarios que no esperaban necesitar una sesión para iniciar sesión.

Cerrar sesión

Para protegerse contra solicitudes de cierre de sesión falsificadas, HTTP La solicitud de cierre de sesión debe estar protegida contra ataques CSRF. La protección contra solicitudes de cierre de sesión falsificadas es necesaria para evitar que un atacante lea la información confidencial de la víctima. Puede encontrar más información sobre el ataque en este blog.

Una posible complicación a la hora de proteger las solicitudes de cierre de sesión HTTP frente a ataques CSRF es que el usuario puede experimentar un tiempo de espera de sesión, lo que provoca que la solicitud sea rechazada. Los tiempos de espera de sesión sorprenderán a los usuarios que no esperaban necesitar una sesión para cerrar sesión.

CSRF y tiempos de espera de sesión

La mayoría de las veces, el token CSRF esperado se almacena en la sesión. Esto significa que una vez que expire la sesión, el servidor no encontrará el token CSRF esperado y rechazará la solicitud HTTP. Hay varias opciones para resolver el problema del tiempo de espera, cada una con sus propias desventajas.

  • La mejor manera de mitigar los efectos del tiempo de espera es usar JavaScript para solicitar un token CSRF cuando el formulario se presenta. Luego, el formulario se actualiza con el token CSRF y se envía.

  • Otra opción es usar JavaScript, que le indica al usuario que su sesión está a punto de expirar. El usuario puede hacer clic en un botón para continuar y actualizar la sesión.

  • Finalmente, el token CSRF esperado se puede almacenar en una cookie. Esto permite que el token CSRF esperado sobreviva a la sesión.

    Uno podría preguntarse por qué el token CSRF esperado no se almacena en una cookie de forma predeterminada. Esto se debe a vulnerabilidades conocidas en las que otro dominio puede configurar encabezados (por ejemplo, para indicar cookies). Por la misma razón, Ruby on Rails more no omite las comprobaciones CSRF si hay un encabezado X-Requested-With presente. Para obtener detalles sobre cómo realizar el exploit, consulte este hilo de webappsec.org. Otra desventaja es que al eliminar el estado (es decir, el tiempo de espera), se pierde la capacidad de forzar la invalidación del token si se ha visto comprometido.

Múltiples componentes (carga de archivos)

Proteger solicitudes de varias partes (cargas de archivos) de ataques CSRF conduce a un pollo y problema del huevo. Para evitar un ataque CSRF, debe leer el cuerpo de la solicitud HTTP para obtener el token CSRF real. Sin embargo, leer el cuerpo significa que el archivo se descargará, lo que a su vez significa que el sitio externo podrá descargar cualquier archivo.

Hay dos opciones para usar la protección CSRF usando multipart/form-data . Cada opción tiene sus compensaciones.

  • Colocar el token CSRF en el cuerpo

  • Colocar el token CSRF en la URL

Antes de integrar la protección CSRF de Spring Security con cargas de archivos de varias partes, primero asegúrese de poder cargar archivos sin CSRF. protección.

Colocar el token CSRF en el cuerpo

La primera opción es agregar el token CSRF real al cuerpo de la solicitud. Si coloca un token CSRF en el cuerpo, el cuerpo se leerá antes de que se produzca la autorización. Esto significa que cualquiera puede alojar archivos temporales en su servidor. Sin embargo, sólo los usuarios autorizados podrán enviar un archivo que será procesado por su aplicación. En general, este es el enfoque recomendado ya que la descarga de un archivo temporal debería tener poco impacto en la mayoría de los servidores.

Agregar un token CSRF a la URL

Si existe la posibilidad de que usuarios no autorizados descarguen archivos temporales files es inaceptable. Una alternativa sería agregar el token CSRF esperado como parámetro de solicitud al atributo de acción en el formulario. La desventaja de este enfoque es la posibilidad de filtrar parámetros de consulta. En general, la mejor manera es colocar datos confidenciales en el cuerpo o en los encabezados, lo que evita que se filtren. Puede encontrar información adicional en la sección 15.1.3 de RFC 2616: Confidencial Codificación de información en el URI".

HiddenHttpMethodFilter

En algunas aplicaciones, se puede utilizar un parámetro de formulario para anular un método HTTP. Por ejemplo, el siguiente formulario podría usarse para tratar el método HTTP como delete en lugar de post.

Formulario del método HTTP oculto en CSRF

<form action="/process"
      method="post">
            <!-- ... -->
	<input type="hidden"
           name="_method"
           value="delete"/>
</form>

El método HTTP se anula en el filtro. Este filtro debe instalarse antes que las herramientas de soporte de Spring Security. Tenga en cuenta que la anulación solo ocurre en post, por lo que es poco probable que cause problemas reales. Sin embargo, la mejor práctica es colocarlo antes de los filtros de Spring Security.

Encabezados de respuesta HTTP seguros

Hay muchos Encabezados para respuestas HTTPque se pueden utilizar para mejorar la seguridad de las aplicaciones web. Esta sección cubre los diversos encabezados de respuesta HTTP para los cuales Spring Security brinda soporte explícito. Si es necesario, Spring Security también se puede configurar para usar encabezados personalizados.

Encabezados de seguridad predeterminados

Spring Security proporciona un conjunto estándar de encabezados relacionados con la seguridad para respuestas HTTP, diseñados para proporcionar seguridad configuración predeterminada.

De forma predeterminada, Spring Security contiene los siguientes encabezados:

Encabezados seguros para respuestas HTTP predeterminadas

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
La seguridad de transporte estricta solo se agrega en solicitudes HTTPS

Si las opciones predeterminadas no se adaptan a sus necesidades, puede eliminar, cambiar o agregar encabezados fácilmente desde estas opciones predeterminadas. Para obtener más información sobre cada uno de estos encabezados, consulte las secciones correspondientes:

  • Administración de caché

  • Opciones de tipo de contenido

  • Seguridad de transporte estricta HTTP

  • Encabezado X-Frame-Options

  • Encabezado X -Protección XSS

Control de caché

De forma predeterminada, Spring Security deshabilita el almacenamiento en caché para proteger el contenido del usuario.

Si el usuario está autorizado a ver información confidencial y luego cerrar sesión, debemos evitar una situación en la que un atacante pueda hacer clic en el botón Atrás y ver información confidencial. Los siguientes encabezados de control de caché se envían de forma predeterminada:

Encabezados de respuesta HTTP con control de caché predeterminado

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
        

Para proporcionar protección predeterminada, Spring Security agrega estos encabezados de forma predeterminada. Sin embargo, si su aplicación proporciona sus propios encabezados de control de caché, Spring Security no aplicará los suyos. Esto permite que las aplicaciones proporcionen almacenamiento en caché para recursos estáticos como CSS y JavaScript.

Opciones de tipo de contenido

Históricamente, los navegadores, incluido Internet Explorer, han intentado adivinar el tipo de contenido de una solicitud usando rastreo de contenido. Esto permitió a los navegadores mejorar la experiencia del usuario al adivinar el tipo de contenido de los recursos donde no se especificaba el tipo de contenido. Por ejemplo, si el navegador acepta un archivo JavaScript que no tiene un tipo de contenido especificado, podrá determinar el tipo de contenido y ejecutarlo.

En caso de que la descarga de contenido esté habilitada, aún quedan muchos pasos adicionales que se deben seguir (por ejemplo, renderizar el documento solo en un dominio específico, asegurarse de que el encabezado Content-Type esté configurado, editar el documento, etc.). Sin embargo, estas medidas van más allá de lo que ofrece Spring Security. También es importante tener en cuenta que al desactivar el rastreo de contenido, debe configurar el tipo de contenido para que todo funcione correctamente.

El problema con el rastreo de contenido era que permitía a los atacantes usar políglotas (es decir, archivos que se pueden utilizar como múltiples tipos de contenido) para realizar ataques XSS. Por ejemplo, algunos sitios pueden permitir a los usuarios enviar y ver un documento posdata válido en el sitio. Un usuario malintencionado podría crear un documento postscript que también sea un archivo JavaScript válido y utilícelo para realizar un ataque XSS.

En Spring Security, el rastreo de contenido está deshabilitado de forma predeterminada agregando el siguiente encabezado a las respuestas HTTP:

encabezado de respuesta HTTP nosniff
X-Content-Type-Options: nosniff

Seguridad de transporte estricta HTTP (HSTS)

Cuando escribe el banco de su sitio web, luego ingresa mybank.example.com o mybank.example.com? Omitir el protocolo https crea una vulnerabilidad potencial a ataques man-in-the-middle. ). Incluso si un sitio redirige a mybank.example.com, un atacante podría interceptar la solicitud HTTP original y manipular la respuesta (por ejemplo, redirigir a mibank.example.com y robar credenciales).

Muchos usuarios se saltan el protocolo https, por lo que el protocolo Seguridad de transporte estricta HTTP (HSTS). Después de agregar mybank.example.com como host HSTS, el navegador puede comprenderlo de antemano. que cualquier solicitud a mybank.example.com debe interpretarse como mybank.example.com. Esto reduce en gran medida la probabilidad de un ataque de intermediario.

Según RFC6797, el encabezado HSTS solo está incrustado en las respuestas HTTPS. Para que el navegador valide el encabezado, primero debe confiar en la autoridad certificadora que firmó el certificado SSL utilizado para crear la conexión (no solo en el certificado SSL).

Una forma de marcar un sitio como HSTS -host está precargando el host en el navegador. La segunda forma es agregar un encabezado Strict-Transport-Security a la respuesta. Por ejemplo, de forma predeterminada, Spring Security agrega el siguiente encabezado, que indica al navegador que trate el dominio como un host HSTS durante un año (hay aproximadamente 31.536.000 segundos en un año):

Encabezado de respuesta HTTP según la especificación de seguridad de transporte estricta
Seguridad-de-transporte-estricta: edad-máxima=31536000; incluirSubDominios; preload

La directiva opcional includeSubDomains le dice al navegador que los subdominios (por ejemplo, Secure.mybank.example.com) también deben considerarse dominios HSTS.

La directiva opcional preload le dice al navegador que el dominio debe precargarse en el navegador como un dominio HSTS. Puede encontrar más información sobre la precarga de HSTS en hstspreload.org.

Fijación de clave pública HTTP (HPKP)

Para habilitar la operación pasiva, Spring Security aún brinda soporte para HPKP en entornos de servlet, pero por las razones enumeradas anteriormente, la seguridad del comando puede ya no recomendamos el uso de HPKP.

HTTP Public Key Fining (HPKP) le dice a un cliente web qué clave pública usar con un servidor web específico para evitar ataques de intermediario (MITM) con certificados falsificados. Cuando se usa correctamente, HPKP puede agregar capas adicionales de protección contra certificados comprometidos. Sin embargo, debido a la complejidad de HPKP, muchos expertos ya no recomiendan su uso y Chrome incluso ha dejado de admitirlo.

Para obtener más información sobre por qué HPKP ya no se recomienda, lea los artículos "¿Está muerta la fijación de clave pública HTTP?" y "Estoy renunciando a HPKP".

Encabezado X-Frame-Options

Permiso para agregar su sitio al marco puede convertirse en un problema de seguridad. Por ejemplo, un estilo CSS inteligente puede engañar a los usuarios para que hagan clic en algo en lo que no tenían intención de hacer clic. Por ejemplo, un usuario que haya iniciado sesión en su banca en línea puede hacer clic en un botón que otorga acceso a otros usuarios. Este tipo de ataque se conoce como clickjacking.

Otro enfoque moderno para combatir el clickjacking es el uso de la especificación de Política de seguridad de contenido (CSP).

Hay formas de contrarrestar los ataques de clickjacking. Por ejemplo, para proteger los navegadores antiguos de ataques de clickjacking, puede utilizar código de ruptura de fotogramas. Si bien no es perfecto, el código de desactivación de marcos es lo mejor que puede hacer para los navegadores antiguos.

Un enfoque más moderno para resolver el problema del clickjacking es utilizar el encabezado X-Frame-Options. De forma predeterminada, Spring Security evita que las páginas se representen en un marco en línea (iframe) cuando se usa el siguiente encabezado:

X-Frame-Options: DENY

X-XSS-Protection Header

Algunos navegadores tienen soporte integrado para filtrar reflejado Ataques XSS. Esto de ninguna manera es infalible, pero ayuda a proteger contra ataques XSS.

El filtrado suele estar habilitado de forma predeterminada, por lo que agregar un encabezado normalmente solo garantiza que esté habilitado e indica al navegador qué hacer al detectarlo un ataque XSS. Por ejemplo, un filtro podría intentar cambiar el contenido de la forma menos invasiva posible para mostrar todo lo que necesita. A veces, un reemplazo de este tipo puede convertirse en una vulnerabilidad XSS. En cambio, es mejor bloquear el contenido que intentar arreglarlo. De forma predeterminada, Spring Security bloquea el contenido usando el siguiente encabezado:

Protección X-XSS: 1; mode=block

Especificación de la política de seguridad de contenido (CSP)

Política de seguridad de contenido (CSP) es un mecanismo que las aplicaciones web pueden utilizar para reducir el riesgo de vulnerabilidades de inyección de contenido, como secuencias de comandos entre sitios (XSS). CSP es una política declarativa que brinda a los autores de aplicaciones web la capacidad de declarar y, en última instancia, comunicar al cliente (agente de usuario) las fuentes desde las cuales la aplicación web espera que se carguen los recursos.

La política de seguridad de contenido no resolverá todos los problemas asociados con las vulnerabilidades de inyección de contenido. En cambio, CSP se puede utilizar para reducir el daño causado por los ataques de inyección de contenido. Como primera línea de defensa, los autores de aplicaciones web deben validar su entrada y codificar la salida.

Una aplicación web puede utilizar CSP si agrega uno de los siguientes encabezados HTTP a la respuesta:

  • Política-de-seguridad-de-contenido

  • Política-de-seguridad-de-contenido-solo-informe

Cada uno de estos encabezados se utiliza como mecanismo para hacer cumplir la política de seguridad para el cliente. Una política de seguridad contiene un conjunto de directivas de política de seguridad, cada una de las cuales es responsable de declarar restricciones en una representación particular de un recurso.

Por ejemplo, una aplicación web podría declarar que espera que se carguen scripts desde ciertas fuentes confiables si agrega como respuesta el siguiente título:

Ejemplo de política de seguridad de contenido
Content-Security-Policy: script-src https://trustedscripts.example.com

El agente de usuario bloqueará un intento de cargar un script desde una fuente distinta a la declarada en la directiva script-src. Además, si la directiva report-uri se declara en el archivo de seguridad política, el agente de usuario informará la infracción a la URL anunciada.

Por ejemplo, si una aplicación web viola la política de seguridad anunciada, el siguiente encabezado de respuesta le indicará al agente de usuario que envíe informes de infracción a la URL anunciada. URL especificada en la directiva de política report-uri.

Política de seguridad de contenido mediante informe -uri
Content-Security-Policy: script-src https://trustedscripts.example.com ; report-uri /csp-report-endpoint/

Informes de abuso son estructuras JSON estándar que se pueden recuperar a través de la API nativa de la aplicación web o a través de un servicio de informes de abuso CSP alojado públicamente, por ejemplo, report-uri.com/.

Encabezado Content-Security-Policy-Report-Onlyda Los autores y administradores de aplicaciones web tienen la capacidad de monitorear las políticas de seguridad en lugar de hacerlas cumplir. Este encabezado se utiliza normalmente al realizar experimentos y/o desarrollar políticas de seguridad para un sitio. Si la política se considera efectiva, se puede aplicar utilizando el campo de encabezado Content-Security-Policy.

Dado el siguiente encabezado de respuesta, la política declara que se pueden cargar scripts de una de dos fuentes posibles.

Informe de política de seguridad de contenido únicamente
Content-Security-Policy-Report-Only: script-src 'self' https://trustedscripts.example.com; report-uri /csp-report-endpoint/

Si un sitio viola esta política al intentar descargar un script de evil.com, el agente de usuario envíe un informe de infracción a la URL especificada por la directiva report-uri, pero aún así permitirá que se cargue el recurso infractor.

Aplicar la especificación de la Política de seguridad de contenido a una aplicación web a menudo no es una tarea tan sencilla. Los siguientes recursos pueden ser de mayor ayuda para desarrollar una política de seguridad eficaz para su sitio.

Introducción a la política de seguridad de contenidos

Guía de CSP: Red de desarrolladores de Mozilla

Recomendación candidata del W3C

Especificación de política de referencia

Política de referencia es un mecanismo que las aplicaciones web pueden utilizar para controlar el campo de referencia que contiene la última página en la que estuvo el usuario.

El enfoque de Spring Security consiste en utilizar la encabezado Política de referencia, que proporciona varias políticas:

Ejemplo de política de referencia
Referrer-Policy: same-origin

El encabezado de respuesta Referrer-Policy indica al navegador que le indique al destinatario la fuente donde se encontraba anteriormente el usuario.

Especificación de política de funciones

Política de funciones es un mecanismo que permite a los desarrolladores web habilitar, deshabilitar y cambiar selectivamente la lógica. de determinadas API y funciones web en el navegador.

Ejemplo de política de funciones
Feature-Policy: geolocation 'self'

Con la Política de funciones, los desarrolladores pueden elegir un conjunto de "políticas" que su navegador aplicará a determinadas funciones utilizadas en su sitio. Estas políticas restringen el acceso de un sitio a las API o cambian el comportamiento predeterminado del navegador para ciertas funciones.

Especificación de la política de permisos

Política de permisos es un mecanismo que permite a los desarrolladores web habilitar, deshabilitar y cambiar selectivamente la lógica de ciertas API y funciones web en el navegador.

Ejemplo de política de permisos
Permissions-Policy: geolocation=(self)

Con la Política de permisos, los desarrolladores pueden elegir un conjunto de “políticas ”que el navegador aplicará a determinadas funciones utilizadas en su sitio. Estas políticas restringen el acceso de un sitio a las API o cambian el comportamiento predeterminado del navegador para determinadas funciones.

Borrar encabezado de datos del sitio

Borrar datos del sitio es un mecanismo mediante el cual cualquier dato (cookies, almacenamiento local y similares) se puede eliminar en el lado del navegador si la respuesta es HTTP, contendrá este encabezado:

Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"

Esta es una medida de limpieza eficaz que se realiza al salir de los sistemas.

Especificación de políticas entre orígenes

Spring Security proporciona soporte para algunos encabezados importantes de la especificación de políticas entre orígenes. Estos encabezados son:

Encabezado de política de apertura de origen cruzado (COOP) permite que el documento de nivel superior rompa la conexión entre su ventana y cualquier otra en el grupo de contexto de visualización (por ejemplo, entre una ventana emergente y su abridor), impidiendo el acceso directo al DOM entre ellos.

La activación Cross-Origin-Embedder-Policy (COEP) evita cargar en un documento cualquier recurso de diferentes orígenes que no otorguen explícitamente permiso de carga al documento.

Encabezado Cross-Origin-Resource-Policy(CORP) le permite controlar el conjunto de orígenes que tienen derecho a agregar un recurso. Esta es una fuerte defensa contra los ataques Spectre porque permite a los navegadores bloquear una respuesta determinada antes de que llegue al proceso del atacante.

Encabezados personalizados

Spring Security contiene mecanismos que le permiten agregar convenientemente los encabezados de seguridad más comunes a su aplicación. Sin embargo, también proporciona enlaces para agregar encabezados personalizados.

HTTP

Toda la comunicación se realiza a través de HTTP, incluido recursos estáticos deben estar protegidos usando TLS.

Como marco, Spring Security no maneja conexiones HTTP y, por lo tanto, no admite HTTPS directamente. Sin embargo, proporciona una serie de funciones que le ayudan a utilizar HTTPS.

Redireccionamiento a HTTPS

Si el cliente utiliza HTTP, puede agregar un redireccionamiento a HTTPS a su Spring Security configuración, al igual que en un entorno de servlet, así como en el entorno WebFlux.

Seguridad de transporte estricta

Spring Security proporciona soporte para el mecanismo de seguridad de transporte estricta y lo activa de forma predeterminada.

Configuración del servidor proxy

Cuando se utiliza un servidor proxy, es importante asegurarse de que la aplicación se haya configurado correctamente. Por ejemplo, muchas aplicaciones contendrán un equilibrador de carga que responde a una solicitud example.com/ reenviándola al servidor de aplicaciones. en 192.168.1:8080. Sin la configuración adecuada, el servidor de aplicaciones no será consciente de la existencia del equilibrador de carga y procesará la solicitud como si el cliente hubiera solicitado 192.168 .1:8080.

Esto se puede solucionar usando RFC 7239 para especificar el uso del equilibrador de carga. Para garantizar la compatibilidad de la aplicación, debe configurar el servidor de aplicaciones para que sea compatible con los encabezados X-Forwarded. Por ejemplo, Tomcat usa RemoteIpValve y Jetty - ForwardedRequestCustomizer. Además, los usuarios de Spring pueden usar ForwardedHeaderFilter.

Los usuarios de Spring Boot pueden usar la propiedad server.use-forward-headers para configurar la aplicación.