Ho sviluppato l'app Rails con API REST per l'accesso dall'applicazione mobile.Come assicurarsi che l'API di Rails sia protetta da CSRF?
Funziona abbastanza bene. Quando l'utente effettua il login dall'applicazione mobile, riceve auth_token
che utilizza nelle sue future richieste all'API. Il problema è che l'API è accessibile anche dal web andando a path/api/v1/... e per questo motivo deve essere protetto da CSRF.
Ho classe BaseApiController
che eredita da ApplicationController
che ha "abilitato" protect_from_forgery
. Ecco ad esempio:
class Api::V1::BaseApiController < ApplicationController
# ...
end
class ApplicationController < ActionController::Base
protect_from_forgery
# ...
end
Ora, quando io non richieste GET al mio API, con auth_token
, la mia richiesta viene completato con successo, ma nei registri posso vedere il famoso WARNING: Can't verify CSRF token authenticity
. Se rimuovo protect_from_forgery
dal mio BaseApiController
, non ricevo alcun avviso (ovviamente), ma la mia API è vulnerabile agli attacchi CSRF (ho creato un semplice modulo HTML che modifica correttamente i dati tra i domini quando non c'è protect_from_forgery
).
La mia domanda è: come assicurare che la mia API rimanga protetta, ma rimuovere anche l'avviso quando si effettuano richieste non GET?
Ecco una delle soluzioni che è venuta in mente, ma sembra più simile a un hack ed esegue una query DB in più:
class Api::V1::BaseApiController < ApplicationController
# ...
def verified_request?
super || User.where(authentication_token: params['auth_token']).count > 0
end
end
Maggiori dettagli sul progetto: Rails 3.2.14, Devise, AngularJS. Il codice sorgente del progetto può essere trovato here.