site rubyonrails rails protect_from_forgery forgery cross ruby-on-rails csrf csrf-protection

ruby-on-rails - rubyonrails - rails session



Razones para el rechazo de token de autenticidad espontánea en el sitio de producción (2)

La aplicación My Rails lanza un ActionController :: InvalidAuthenticityToken de vez en cuando. Ocurre espontáneamente una vez al mes más o menos. Como no creo que haya otro sitio intentando un ataque CSRF, comencé a reflexionar sobre estos eventos raros. Mi conclusión hasta ahora:

  • Robots al azar?
  • ¿Las personas esperan demasiado para enviar el formulario para que caduque en el servidor?

¿Existen otras razones para tales falsos rechazos positivos?

Y por favor no explique qué es CSRF ;-)

Aquí hay algunos registros ...

F, [2016-12-06T16:03:59.050673 #15136] FATAL -- : ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken): actionpack (4.2.7) lib/action_controller/metal/request_forgery_protection.rb:181:in `handle_unverified_request'' actionpack (4.2.7) lib/action_controller/metal/request_forgery_protection.rb:209:in `handle_unverified_request'' devise (4.2.0) lib/devise/controllers/helpers.rb:253:in `handle_unverified_request'' actionpack (4.2.7) lib/action_controller/metal/request_forgery_protection.rb:204:in `verify_authenticity_token'' activesupport (4.2.7) lib/active_support/callbacks.rb:432:in `block in make_lambda'' activesupport (4.2.7) lib/active_support/callbacks.rb:164:in `block in halting'' activesupport (4.2.7) lib/active_support/callbacks.rb:504:in `block in call'' activesupport (4.2.7) lib/active_support/callbacks.rb:504:in `each'' activesupport (4.2.7) lib/active_support/callbacks.rb:504:in `call'' activesupport (4.2.7) lib/active_support/callbacks.rb:92:in `__run_callbacks__'' activesupport (4.2.7) lib/active_support/callbacks.rb:778:in `_run_process_action_callbacks'' activesupport (4.2.7) lib/active_support/callbacks.rb:81:in `run_callbacks'' actionpack (4.2.7) lib/abstract_controller/callbacks.rb:19:in `process_action'' actionpack (4.2.7) lib/action_controller/metal/rescue.rb:29:in `process_action'' actionpack (4.2.7) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'' activesupport (4.2.7) lib/active_support/notifications.rb:164:in `block in instrument'' activesupport (4.2.7) lib/active_support/notifications/instrumenter.rb:20:in `instrument'' activesupport (4.2.7) lib/active_support/notifications.rb:164:in `instrument'' actionpack (4.2.7) lib/action_controller/metal/instrumentation.rb:30:in `process_action'' actionpack (4.2.7) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'' actionpack (4.2.7) lib/abstract_controller/base.rb:137:in `process'' actionview (4.2.7) lib/action_view/rendering.rb:30:in `process'' actionpack (4.2.7) lib/action_controller/metal.rb:196:in `dispatch'' actionpack (4.2.7) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'' actionpack (4.2.7) lib/action_controller/metal.rb:237:in `block in action'' actionpack (4.2.7) lib/action_dispatch/routing/route_set.rb:74:in `dispatch'' actionpack (4.2.7) lib/action_dispatch/routing/route_set.rb:43:in `serve'' actionpack (4.2.7) lib/action_dispatch/routing/mapper.rb:49:in `serve'' actionpack (4.2.7) lib/action_dispatch/journey/router.rb:43:in `block in serve'' actionpack (4.2.7) lib/action_dispatch/journey/router.rb:30:in `each'' actionpack (4.2.7) lib/action_dispatch/journey/router.rb:30:in `serve'' actionpack (4.2.7) lib/action_dispatch/routing/route_set.rb:817:in `call'' turnout (2.3.1) lib/rack/turnout.rb:25:in `call'' omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'' omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'' omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'' omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'' rack-attack (4.4.1) lib/rack/attack.rb:107:in `call'' exception_notification (4.2.1) lib/exception_notification/rack.rb:32:in `call'' warden (1.2.6) lib/warden/manager.rb:35:in `block in call'' warden (1.2.6) lib/warden/manager.rb:34:in `catch'' warden (1.2.6) lib/warden/manager.rb:34:in `call'' rack (1.6.4) lib/rack/etag.rb:24:in `call'' rack (1.6.4) lib/rack/conditionalget.rb:38:in `call'' rack (1.6.4) lib/rack/head.rb:13:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/params_parser.rb:27:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/flash.rb:260:in `call'' rack (1.6.4) lib/rack/session/abstract/id.rb:225:in `context'' rack (1.6.4) lib/rack/session/abstract/id.rb:220:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/cookies.rb:560:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'' activesupport (4.2.7) lib/active_support/callbacks.rb:88:in `__run_callbacks__'' activesupport (4.2.7) lib/active_support/callbacks.rb:778:in `_run_call_callbacks'' activesupport (4.2.7) lib/active_support/callbacks.rb:81:in `run_callbacks'' actionpack (4.2.7) lib/action_dispatch/middleware/callbacks.rb:27:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'' railties (4.2.7) lib/rails/rack/logger.rb:38:in `call_app'' railties (4.2.7) lib/rails/rack/logger.rb:20:in `block in call'' activesupport (4.2.7) lib/active_support/tagged_logging.rb:68:in `block in tagged'' activesupport (4.2.7) lib/active_support/tagged_logging.rb:26:in `tagged'' activesupport (4.2.7) lib/active_support/tagged_logging.rb:68:in `tagged'' railties (4.2.7) lib/rails/rack/logger.rb:20:in `call'' ahoy_matey (1.4.2) lib/ahoy/engine.rb:22:in `call_with_quiet_ahoy'' request_store (1.3.1) lib/request_store/middleware.rb:9:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/request_id.rb:21:in `call'' rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'' rack (1.6.4) lib/rack/runtime.rb:18:in `call'' activesupport (4.2.7) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'' rack (1.6.4) lib/rack/sendfile.rb:113:in `call'' actionpack (4.2.7) lib/action_dispatch/middleware/ssl.rb:24:in `call'' railties (4.2.7) lib/rails/engine.rb:518:in `call'' railties (4.2.7) lib/rails/application.rb:165:in `call'' /usr/lib/ruby/vendor_ruby/phusion_passenger/rack/thread_handler_extension.rb:97:in `process_request'' /usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler/thread_handler.rb:160:in `accept_and_process_next_request'' /usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler/thread_handler.rb:113:in `main_loop'' /usr/lib/ruby/vendor_ruby/phusion_passenger/request_handler.rb:416:in `block (3 levels) in start_threads'' /usr/lib/ruby/vendor_ruby/phusion_passenger/utils.rb:113:in `block in create_thread_and_abort_on_exception''


Estoy con Dorian en este caso en cuanto a la solución.

Si está buscando la causa, estoy bastante seguro de que github.com/rails/rails/issues/21948 verdadero, especialmente en esta pequeña sección:

# El navegador se cierra, borrando las cookies de sesión

# El navegador se vuelve a abrir, vuelve a cargar la página desde el caché sin hacer una solicitud

Esto es especialmente cierto ya que, por defecto, Rails usa turbolinks que fomentan el almacenamiento en caché (por defecto, 10 páginas si recuerdo).

Otra forma en que esto puede ser potencialmente replicado es haciendo que un usuario cargue su DOM (y por lo tanto sus cookies / sesión) y luego haga que destruyan manualmente su sesión o cookies a través de las herramientas de administración del navegador (por ejemplo: chrome: // settings). Esto también debería reproducir el error, ya que tendrá la etiqueta oculta para csrf en el formulario, pero no la cookie de sesión ... y necesita ambas.


Probablemente debería anular la sesión en su entorno de producción en lugar de lanzar una excepción:

En su ApplicationController (o cualquier controlador que le preocupe) agregue:

protect_from_forgery with: :null_session

Si está realmente preocupado por eso, mi consejo sería, por ejemplo, iniciar sesión en Bugsnag para cometer un error y allí podrá revisar la solicitud y comprender por qué sucedió.