2015-12-10 10 views
5

Ich entwickle eine Rails 4-App, die eine mobile App über eine API bereitstellt und über eine Webbenutzeroberfläche für Administratoren verfügt, um die Anwendung zu verwalten. Es gibt auch ein paar Webseiten, die den Benutzern angezeigt werden (erfolgreiche E-Mail-Bestätigung und Zurücksetzen des Passworts).Korrekte Verwendung von protect_from_forgery in der Rails-App für Web und API

Ich habe zwei Sätze von Controllern erstellt: ein Satz erbt von APIController und der andere von AdminController. Beide erben von ApplicationController. Der verbleibende Controller, der für Benutzer-Webseiten verantwortlich ist, erbt ebenfalls von ApplicationController.

In Anbetracht dieses Schemas bin ich unsicher, wie CSRF-Schutz mit protect_from_forgery ordnungsgemäß implementiert werden kann. Ich habe derzeit folgendes:

class ApplicationController < ActionController::Base 
    # ... 
end 

module API 
    class APIController < ApplicationController 
    protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' } 
    # ... 
    end 
end 

module Admin 
    class AdminController < ApplicationController 
    protect_from_forgery with: :exception 
    # ... 
    end 
end 

class UsersController < ApplicationController 
    protect_from_forgery with: :exception 
    # ... 
end 

Also meine Frage ist: ist das korrekt? Gibt es eine Möglichkeit, es zu verbessern? Ist die Überprüfung im APIController sinnlos, da alle API-Anfragen sowieso nur JSON sind?

Brakeman beschwerte sich, dass es in ApplicationController keinen protect_from_forgery-Aufruf gibt, aber vielleicht sieht er die Aufrufe in den Unterklassen nicht.

Vielen Dank im Voraus!

Antwort

2

können Sie sehen here, on their (brakeman) Github page, dass es für die Gegenwart nur auf der ApplicationController prüft

Ihre Admin und User-Controller sind in Ordnung mit dem protect_from_forgery with: :exception

Das Standardverhalten auf Schienen 4 für protect_from_forgery ist :null_session, Sie entfernen können die Option with: wenn Sie möchten.

Über die Verbesserung, würde ich eine Möglichkeit implementieren, um ein Token im Benutzer zu speichern und für jede Anfrage übereinstimmen, auf die Weise würde der Benutzer die API anfordern würde sein Token jede Anfrage senden müssen. Auf diese Weise vermeiden Sie die Notwendigkeit, das CSRF-Token zu erhalten und dann die Anfrage mit diesem Token zu senden. Für mobile Benutzer beispielsweise ist dies eine zusätzliche Anforderung, bei der Sie nur durch Speichern des richtigen Tokens eine Lösung finden könnten. Wenn jedoch jemand dieses Token erhält, könnte es als Benutzer übergeben werden und die Daten ändern. Aber Sie können nach mehr Möglichkeiten suchen, wie Sie das sicherer machen können.

Die CSRF kann passieren, wenn Sie das Token in Sitzungen oder Cookies speichern, müssten Sie sich selbstständig darum kümmern, falls Sie sich dafür entscheiden, so zu speichern.

Wenn Sie beabsichtigen, die API für Handys zu verwenden, speichern Sie das Token (in der Strategie, die ich zuerst sagte) auf dem Handy (Speicher oder lokale db) und es wird sicherer sein.