Una vieja pregunta pero la seguridad es lo suficientemente importante como para sentir que merece una respuesta completa. Como se discutió en este documento question, aún existe cierto riesgo de CSRF incluso con API. Sí, se supone que los navegadores evitan esto por defecto, pero como no tiene el control completo del navegador y de los complementos que el usuario ha instalado, se debe considerar como una mejor práctica para protegerse contra CSRF en su API.
La forma en que lo he visto a veces es analizar la metaetiqueta CSRF desde la propia página HTML. Realmente no me gusta esto, ya que no encaja bien con la forma en que funcionan muchas aplicaciones de una sola página + API hoy en día y creo que el token CSRF debe enviarse en cada solicitud, independientemente de si es HTML, JSON o XML.
Así que sugeriría pasar un token CSRF como un valor de cookie o encabezado a través de un filtro posterior para todas las solicitudes. La API simplemente puede volver a enviar esa vuelta como un valor de encabezado de X-CSRF-Token
que Rails ya verifica.
Así es como lo hice con AngularJS:
# In my ApplicationController
after_filter :set_csrf_cookie
def set_csrf_cookie
if protect_against_forgery?
cookies['XSRF-TOKEN'] = form_authenticity_token
end
end
AngularJS automatically looks for a cookie nombrados XSRF-TOKEN
pero no dude en llamarlo cualquier cosa que desee para sus propósitos. Luego, cuando envíe un mensaje POST/PUT/DELETE, debe establecer la propiedad del encabezado X-CSRF-Token
que Rails busca automáticamente.
Desafortunadamente, AngualrJS ya envía de vuelta la cookie XSRF-TOKEN
en un valor de encabezado de X-XSRF-TOKEN
. Es fácil de anular el comportamiento por defecto de Rails para acomodar esto en ApplicationController
así:
protected
def verified_request?
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
end
para los carriles 4.2 hay una construida en ayudante ahora para validar CSRF que se debe utilizar.
protected
def verified_request?
super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN'])
end
Espero que sea útil.
EDIT: en un discussion on this for a Rails pull-request presenté que pasar el token CSRF a través de la API para iniciar sesión es una práctica particularmente mala (por ejemplo, alguien podría crear un inicio de sesión de terceros para su sitio que use credenciales de usuario en lugar de tokens) . Así que cavet emptor. Depende de usted decidir qué tan preocupado está sobre eso para su aplicación. En este caso, podría seguir utilizando el enfoque anterior, pero solo devolverá la cookie CSRF a un navegador que ya tenga una sesión autenticada y no para cada solicitud. Esto evitará enviar un inicio de sesión válido sin usar la metaetiqueta CSRF.
La página que he vinculado no coincide: "Ciertas combinaciones de complementos de navegador y redireccionamientos HTTP se pueden utilizar para engañar al navegador del usuario para realizar solicitudes entre dominios que incluyen encabezados HTTP arbitrarios especificados por el atacante. Un atacante puede utilizarlo para suplantar ajax y las solicitudes API y eludir la protección CSRF incorporada y atacar con éxito una aplicación ". –
"Esto no es relevante para las API, ya que no se ejecutan en el navegador": a veces el navegador * es * el cliente de la API, es decir, – antinome
http://stackoverflow.com/questions/9362910/rails -warning-cant-verify-csrf-token-authenticity-for-json-devise-requests/10049965 # 10049965 – montrealmike