Me encuentro con algunos problemas relacionados con el token de autenticidad en Rails, como lo he hecho muchas veces.
Pero realmente no quiero resolver este problema y continuar. Realmente me gustaría entender el token Autenticidad. Bueno, mi pregunta es, ¿tiene alguna fuente completa de información sobre este tema o pasaría su tiempo explicando los detalles aquí?
ruby-on-rails
ruby
authenticity-token
Ricardo Acras
fuente
fuente
Respuestas:
Lo que pasa
Cuando el usuario ve un formulario para crear, actualizar o destruir un recurso, la aplicación Rails crea un formulario aleatorio
authenticity_token
, almacena este token en la sesión y lo coloca en un campo oculto en el formulario. Cuando el usuario envía el formulario, Rails lo buscaauthenticity_token
, lo compara con el almacenado en la sesión y, si coinciden, se permite que la solicitud continúe.Por que sucede
Como el token de autenticidad se almacena en la sesión, el cliente no puede conocer su valor. Esto evita que las personas envíen formularios a una aplicación Rails sin ver el formulario dentro de esa aplicación. Imagine que está utilizando el servicio A, inició sesión en el servicio y todo está bien. Ahora imagine que fue a utilizar el servicio B, vio una imagen que le gusta y presionó la imagen para ver un tamaño mayor. Ahora, si había algún código maligno en el servicio B, podría enviar una solicitud al servicio A (en el que ha iniciado sesión) y solicitar que elimine su cuenta enviando una solicitud a
http://serviceA.com/close_account
. Esto es lo que se conoce como CSRF (Cross Site Request Forgery) .Si el servicio A está usando tokens de autenticidad, este vector de ataque ya no es aplicable, ya que la solicitud del servicio B no contendría el token de autenticidad correcto y no se permitirá que continúe.
Los documentos de la API describen detalles sobre la metaetiqueta:
Notas
Tenga en cuenta que Rails solo verifica los métodos no idempotentes (POST, PUT / PATCH y DELETE). La solicitud GET no se verifica para el token de autenticidad. ¿Por qué? porque la especificación HTTP establece que las solicitudes GET son idempotentes y no deberían crear, alterar o destruir recursos en el servidor, y la solicitud debería ser idempotente (si ejecuta el mismo comando varias veces, debería obtener el mismo resultado cada vez).
Además, la implementación real es un poco más complicada como se definió al principio, lo que garantiza una mejor seguridad. Rails no emite el mismo token almacenado con cada formulario. Tampoco genera y almacena un token diferente cada vez. Genera y almacena un hash criptográfico en una sesión y emite nuevos tokens criptográficos, que se pueden comparar con el almacenado, cada vez que se procesa una página. Ver request_forgery_protection.rb .
Lecciones
Úselo
authenticity_token
para proteger sus métodos no idempotentes (POST, PUT / PATCH y DELETE). También asegúrese de no permitir ninguna solicitud GET que pueda modificar los recursos en el servidor.EDITAR: Verifique el comentario de @erturne sobre las solicitudes GET como idempotentes. Él lo explica de una mejor manera que lo que he hecho aquí.
fuente
El token de autenticidad está diseñado para que sepa que su formulario se envía desde su sitio web. Se genera a partir de la máquina en la que se ejecuta con un identificador único que solo su máquina puede conocer, lo que ayuda a prevenir ataques de falsificación de solicitudes entre sitios.
Si simplemente está teniendo dificultades con los rieles que le niegan el acceso al script AJAX, puede usar
para generar el token correcto cuando está creando su formulario.
Puede leer más al respecto en la documentación .
fuente
¿Qué es CSRF?
El token de autenticidad es una contramedida para la falsificación de solicitudes entre sitios (CSRF). ¿Qué es CSRF, preguntas?
Es una forma en que un atacante puede potencialmente secuestrar sesiones sin siquiera conocer los tokens de sesión.
Escenario :
Solución CSRF :
fuente
Ejemplo de ataque mínimo que se evitaría: CSRF
En mi sitio web
evil.com
lo convenzo de enviar el siguiente formulario:Si ha iniciado sesión en su banco a través de cookies de sesión, las cookies se enviarán y la transferencia se realizará sin que usted lo sepa.
Ahí es donde entra en juego el token CSRF:
Entonces el formulario en un navegador auténtico se vería así:
Por lo tanto, mi ataque fallaría, ya que no estaba enviando el
authenticity_token
parámetro, y no hay forma de que lo haya adivinado ya que es un gran número aleatorio.Esta técnica de prevención se llama Patrón de token de sincronizador .
Política del mismo origen
Pero, ¿qué sucede si el atacante realizó dos solicitudes con JavaScript, una para leer el token y la segunda para realizar la transferencia?
¡El patrón de token sincronizador solo no es suficiente para evitar eso!
Aquí es donde la Política del mismo origen viene al rescate, como lo he explicado en: /security/8264/why-is-the-same-origin-policy-so-important/72569# 72569
Cómo envía los tokens Rails
Cubierto en: Rails: ¿Cómo funciona csrf_meta_tag?
Básicamente:
Los ayudantes HTML como
form_tag
agregar un campo oculto al formulario para usted si no es un formulario GETAjax se ocupa automáticamente de jquery-ujs , que lee el token de los
meta
elementos agregados a su encabezado porcsrf_meta_tags
(presente en la plantilla predeterminada) y lo agrega a cualquier solicitud realizada.uJS también intenta actualizar el token en formularios en fragmentos en caché obsoletos.
Otros enfoques de prevención
X-Requested-With
:Origin
encabezado: /security/91165/why-is-the-synchronizer-token-pattern-preferred-over-the-origin-header-check-tofuente
El token de autenticidad se usa para evitar ataques de falsificación de solicitudes entre sitios (CSRF). Para comprender el token de autenticidad, primero debe comprender los ataques CSRF.
CSRF
Supongamos que usted es el autor de
bank.com
. Tiene un formulario en su sitio que se utiliza para transferir dinero a una cuenta diferente con una solicitud GET:Un pirata informático podría enviar una solicitud HTTP al servidor diciendo
GET /transfer?amount=$1000000&account-to=999999
, ¿verdad?Incorrecto. El ataque de los hackers no funcionará. El servidor básicamente pensará?
¿Cómo sabe esto el servidor? Porque no hay
session_id
cookies que autentiquen al solicitante.Cuando inicia sesión con su nombre de usuario y contraseña, el servidor establece una
session_id
cookie en su navegador. De esa manera, no tiene que autenticar cada solicitud con su nombre de usuario y contraseña. Cuando su navegador envía lasession_id
cookie, el servidor sabe:Un hacker podría pensar:
El navegador de los usuarios tiene un conjunto de cookies establecidas para el
bank.com
dominio. Cada vez que el usuario realiza una solicitud albank.com
dominio, se envían todas las cookies. Incluyendo elsession_id
galleta.Así que si un pirata informático podría conseguir que haga la solicitud GET que transfiere dinero a su cuenta, tendría éxito. ¿Cómo podría engañarte para que lo hagas? Con falsificación de solicitud de sitio cruzado.
Es bastante simple, en realidad. El hacker podría hacerte visitar su sitio web. En su sitio web, podría tener la siguiente etiqueta de imagen:
Cuando el navegador del usuario encuentre esa etiqueta de imagen, realizará una solicitud GET a esa URL. Y dado que la solicitud proviene de su navegador, enviará con ella todas las cookies asociadas
bank.com
. Si el usuario había iniciado sesión recientemente enbank.com
... lasession_id
cookie se establecerá, ¡y el servidor pensará que el usuario tenía la intención de transferir $ 1,000,000 a la cuenta 999999!Eso no es suficiente. ¿Qué pasa si alguien publica esa imagen en Facebook y aparece en su muro? ¿Qué pasa si se inyecta en un sitio que estás visitando con un ataque XSS?
No es verdad. Un formulario que envía una solicitud POST puede generarse dinámicamente. Aquí está el ejemplo de la Guía de Rails sobre Seguridad :
Token de autenticidad
Cuando tienes
ApplicationController
esto:Esta:
Se compila en esto:
En particular, se genera lo siguiente:
Para protegerse contra los ataques CSRF, si Rails no ve el token de autenticidad enviado junto con una solicitud, no considerará la solicitud como segura.
¿Cómo se supone que un atacante sabe qué es este token? Se genera un valor diferente al azar cada vez que se genera el formulario:
Un ataque Cross Site Scripting (XSS): así es como. Pero esa es una vulnerabilidad diferente para un día diferente.
fuente
Este
Authenticity Token
es el método de rails para evitar 'ataques de falsificación de solicitudes entre sitios (CSRF o XSRF)' .En pocas palabras, se asegura de que las solicitudes PUT / POST / DELETE (métodos que pueden modificar el contenido) a su aplicación web se realicen desde el navegador del cliente y no desde un tercero (un atacante) que tenga acceso a una cookie creada en el lado del cliente.
fuente
ya que
Authenticity Token
es muy importante, y en Rails 3.0+ puedes usarcrear
en cualquier sitio
fuente
XSS
en la página de inicio de sesión, no con fines nefastos, sino para crear una nueva sesión con un nombre de usuario precargado. Ahora sé que solo puedo usarvalue="token_value"
.Tenga en cuenta que el mecanismo del token de autenticidad puede generar condiciones de carrera si tiene varias solicitudes simultáneas del mismo cliente. En esta situación, su servidor puede generar múltiples tokens de autenticidad cuando solo debería haber uno, y el cliente que recibe el token anterior en un formulario fallará en su próxima solicitud porque el token de cookie de sesión se ha sobrescrito. Hay un informe sobre este problema y una solución no completamente trivial aquí: http://www.paulbutcher.com/2007/05/race-conditions-in-rails-sessions-and-how-to-fix-them/
fuente
Métodos donde
authenticity_token
se requierePor qué es obligatorio
fuente
¿Qué es una autenticación_token?
Esta es una cadena aleatoria utilizada por la aplicación rails para asegurarse de que el usuario solicita o realiza una acción desde la página de la aplicación, no desde otra aplicación o sitio.
¿Por qué es necesaria una autenticación_token?
Para proteger su aplicación o sitio de la falsificación de solicitudes entre sitios.
¿Cómo agregar un token de autenticación a un formulario?
Si está generando un formulario usando form_for tag, se agrega automáticamente un token de autenticación, de lo contrario puede usarlo
<%= csrf_meta_tag %>
.fuente