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í:
<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í:
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:
<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í:
<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í:
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í:
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:
<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
{ "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:
<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
.
<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:
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
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:
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:
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):
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:
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
.
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-Only
da 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.
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:
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.
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.
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.