2014-11-18 3 views
7

Ich habe eine Rails-App, die in einem Docker-Container ausgeführt wird, der eine IP-Adresse zugewiesen ist. Eingehende Anfragen an den Host-Rechner 51.x.x.x werden an die App rails in 172.17.0.3 weitergeleitet. Insbesondere wurde dies als solches getan:Port-weitergeleitete Rails-App in Docker scheint CSRF-Ausnahme zu verursachen

docker run -p 8080:8080 rails_app 

jedoch Rails-Anwendung führt Can't verify CSRF token authenticity Fehler, wenn ein Benutzer einige der Seiten zuzugreifen versucht. Mein Verdacht ist, dass Rails denkt, dass die eingehende Anfrage ein Angriff ist, da die IP des Ziels nicht mit der IP der Rails-App übereinstimmt - dh Benutzeranfragen werden an den Host-Rechner 51.x.x.x gerichtet, während Rails aktueller Standort 172.17.0.3

ist

Gibt es eine Möglichkeit für mich, Rails mitzuteilen, dass diese Anfragen echt sind? Als zusätzliche Information verwende ich devise für die Authentifizierung und unicorn als Server.

Einige von Ihnen könnten versucht sein, die Änderung protect_from_forgery with: :exception zu :null_session vorzuschlagen, aber die Anwendung funktioniert gut, wenn sie nicht hinter einem Proxy platziert ist. Außerdem funktioniert ein Teil der Logik nicht, wenn ich diesen Teil ändere, da ich denke, dass die Einstellung mit der Art und Weise kollidiert, wie eine Benutzersitzung gehandhabt wird.

Dies ist das Layout meines Netzwerks:

(user from public network) ----> (proxy) ----> (rails app on a private network) 
     (202.x.x.x)   (51.x.x.x)    (172.x.x.x) 

EDIT: Die App in development Einstellungen ist. Hier ist der Fehler, den ich in log/development.log Dateien bekommen habe.

Started POST "/register" for 202.x.x.x at 2014-11-18 02:27:11 +0000 
Processing by UsersController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"aBG3nIAKK1ALMJ1DDYFlMkmqISMBMZc3iLmaeD2byG8=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}} 
Can't verify CSRF token authenticity 
Completed 422 Unprocessable Entity in 2ms 

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken): 
    actionpack (4.1.4) lib/action_controller/metal/request_forgery_protection.rb:176:in `handle_unverified_request' 
    actionpack (4.1.4) lib/action_controller/metal/request_forgery_protection.rb:202:in `handle_unverified_request' 
    devise (3.4.0) lib/devise/controllers/helpers.rb:251:in `handle_unverified_request' 
    actionpack (4.1.4) lib/action_controller/metal/request_forgery_protection.rb:197:in `verify_authenticity_token' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:424:in `block in make_lambda' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:160:in `call' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:160:in `block in halting' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:166:in `call' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:166:in `block in halting' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:149:in `call' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:149:in `block in halting_and_conditional' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:149:in `call' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:149:in `block in halting_and_conditional' 
activesupport (4.1.4) lib/active_support/callbacks.rb:86:in `run_callbacks' 
    actionpack (4.1.4) lib/abstract_controller/callbacks.rb:19:in `process_action' 
    actionpack (4.1.4) lib/action_controller/metal/rescue.rb:29:in `process_action' 
    actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:31:in `block in process_action' 
    activesupport (4.1.4) lib/active_support/notifications.rb:159:in `block in instrument' 
    activesupport (4.1.4) lib/active_support/notifications/instrumenter.rb:20:in `instrument' 
    activesupport (4.1.4) lib/active_support/notifications.rb:159:in `instrument' 
    actionpack (4.1.4) lib/action_controller/metal/instrumentation.rb:30:in `process_action' 
    actionpack (4.1.4) lib/action_controller/metal/params_wrapper.rb:250:in `process_action' 
    activerecord (4.1.4) lib/active_record/railties/controller_runtime.rb:18:in `process_action' 
    actionpack (4.1.4) lib/abstract_controller/base.rb:136:in `process' 
    actionview (4.1.4) lib/action_view/rendering.rb:30:in `process' 
    actionpack (4.1.4) lib/action_controller/metal.rb:196:in `dispatch' 
    actionpack (4.1.4) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch' 
    actionpack (4.1.4) lib/action_controller/metal.rb:232:in `block in action' 
    actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:in `call' 
    actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:82:in `dispatch' 
    actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:50:in `call' 
    actionpack (4.1.4) lib/action_dispatch/routing/mapper.rb:45:in `call' 
    actionpack (4.1.4) lib/action_dispatch/journey/router.rb:71:in `block in call' 
    actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in `each' 
    actionpack (4.1.4) lib/action_dispatch/journey/router.rb:59:in `call' 
    actionpack (4.1.4) lib/action_dispatch/routing/route_set.rb:678:in `call' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!' 
    omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call' 
    warden (1.2.3) lib/warden/manager.rb:35:in `block in call' 
    warden (1.2.3) lib/warden/manager.rb:34:in `catch' 
    warden (1.2.3) lib/warden/manager.rb:34:in `call' 
    rack (1.5.2) lib/rack/etag.rb:23:in `call' 
    rack (1.5.2) lib/rack/conditionalget.rb:35:in `call' 
    rack (1.5.2) lib/rack/head.rb:11:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/params_parser.rb:27:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/flash.rb:254:in `call' 
    rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context' 
    rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/cookies.rb:560:in `call' 
    activerecord (4.1.4) lib/active_record/query_cache.rb:36:in `call' 
    activerecord (4.1.4) lib/active_record/connection_adapters/abstract/connection_pool.rb:621:in `call' 
    activerecord (4.1.4) lib/active_record/migration.rb:380:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call' 
    activesupport (4.1.4) lib/active_support/callbacks.rb:82:in `run_callbacks' 
    actionpack (4.1.4) lib/action_dispatch/middleware/callbacks.rb:27:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/reloader.rb:73:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/remote_ip.rb:76:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call' 
    railties (4.1.4) lib/rails/rack/logger.rb:38:in `call_app' 
    railties (4.1.4) lib/rails/rack/logger.rb:20:in `block in call' 
    activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in `block in tagged' 
    activesupport (4.1.4) lib/active_support/tagged_logging.rb:26:in `tagged' 
    activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in `tagged' 
    railties (4.1.4) lib/rails/rack/logger.rb:20:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/request_id.rb:21:in `call' 
    rack (1.5.2) lib/rack/methodoverride.rb:21:in `call' 
    rack (1.5.2) lib/rack/runtime.rb:17:in `call' 
    activesupport (4.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in `call' 
    rack (1.5.2) lib/rack/lock.rb:17:in `call' 
    actionpack (4.1.4) lib/action_dispatch/middleware/static.rb:64:in `call' 
    rack-cors (0.2.9) lib/rack/cors.rb:54:in `call' 
    rack (1.5.2) lib/rack/sendfile.rb:112:in `call' 
    railties (4.1.4) lib/rails/engine.rb:514:in `call' 
    railties (4.1.4) lib/rails/application.rb:144:in `call' 
    rack (1.5.2) lib/rack/lint.rb:49:in `_call' 
    rack (1.5.2) lib/rack/lint.rb:37:in `call' 
    rack (1.5.2) lib/rack/showexceptions.rb:24:in `call' 
    rack (1.5.2) lib/rack/commonlogger.rb:33:in `call' 
    sinatra (1.4.5) lib/sinatra/base.rb:217:in `call' 
    rack (1.5.2) lib/rack/chunked.rb:43:in `call' 
    rack (1.5.2) lib/rack/content_length.rb:14:in `call' 
    unicorn (4.8.3) lib/unicorn/http_server.rb:576:in `process_client' 
    unicorn (4.8.3) lib/unicorn/http_server.rb:670:in `worker_loop' 
    unicorn (4.8.3) lib/unicorn/http_server.rb:525:in `spawn_missing_workers' 
    unicorn (4.8.3) lib/unicorn/http_server.rb:140:in `start' 
    unicorn (4.8.3) bin/unicorn:126:in `<top (required)>' 
+0

Haben Sie jemals herausgefunden? Ich habe gerade eine Produktionsumgebung auf einer Ubuntu-VM mit Docker-Containern ... flask, mysql, nginx und uwsgi erstellt. Ich erhalte auch CRSF-Token-Fehler in Formularen. – Chockomonkey

+0

Ich habe mir selbst etwas Ähnliches gedacht ... Wenn Sie SERVER_NAME in Ihrer Konfiguration definiert haben, versuchen Sie, es zu entfernen. – Chockomonkey

+0

@Chockomonkey Können Sie erweitern, was Sie meinen? Meinst du, wenn Sie 'SERVER_NAME' als Umgebungsvariable definiert haben? –

Antwort

1

Aus einer flüchtigen Lektüre des 'protect_from_forgery method', finden wir folgendes:

def protect_from_forgery(options = {}) 
    self.forgery_protection_strategy = protection_method_class(options[:with] || :null_session) 
    self.request_forgery_protection_token ||= :authenticity_token 
    prepend_before_action :verify_authenticity_token, options 
    append_after_action :verify_same_origin_request 
    end 

, die einen vor der Aktion Rückruf 'verify_authenticity_token' genannt hat. Wenn wir an der Quelle suchen finden wir folgendes:

def verify_authenticity_token 
    mark_for_same_origin_verification! 

    if !verified_request? 
     logger.warn "Can't verify CSRF token authenticity" if logger 
     handle_unverified_request 
    end 
    end 

Von dort stellen wir fest, dass es nennt ‚verified_request?‘.

Angesichts der Art der erhobenen Ausnahme würde ich denken, dass eine oder mehrere dieser Bedingungen nicht erfüllt werden. Ich glaube nicht, dass es etwas mit der IP-Adressierung zu tun hat.

0

Wenn Ihre Rails-App über Nicht-SSL mit Ihrem Proxy kommuniziert, kann ein Problem auftreten, bei dem Ihr ActiveRecord :: SessionStore aufgrund dieses Szenarios eine Anpassung verursacht.

Unsere fix war, um die Session-Speicher unsicher zu machen:

OurApplication::Application.config.session_store :active_record_store, secure: false

Edit: Noch keine fix noch ... Wir sind wahrscheinlich bei den Apps zu beenden zu haben, um die SSL zu machen im Gegensatz zum Proxy darüber.

Also für uns hatte das Problem am Ende nichts mit SSL zu tun. Wir hatten einen JavaScript-Aufruf beim ersten Laden der Seite, der versuchte, einen Handshake gegen einen Backend-Dienst (über einen POST) durchzuführen, aber wir hatten unseren HAProxy nicht richtig konfiguriert, um Anrufe an diesen Dienst weiterzuleiten, also stattdessen der POST Schienen treffen.Obwohl Rails einen 404 für die Route zurückgegeben hat, wurde auch die Sitzung aufgrund des fehlenden CSRF-Tokens in der Anforderung zurückgesetzt. Durch das Reparieren des HAProxy-Routings wurde das Problem behoben.

Unser Szenario hat wahrscheinlich fast nichts mit Ihrem zu tun, und in Rails 4 haben sie das Standardverhalten protect_from_forgery gemacht, um eine Ausnahme auszulösen, anstatt die Sitzung zurückzusetzen. Oh, und wir haben auch letztlich müssen die Session-Speicher zu unsicher setzen:

OurApplication::Application.config.session_store :active_record_store, secure: false

Verwandte Themen