2010-09-22 2 views
26

Dans un contrôleur Rails, je peux définir un cookie comme celui-ci:Comment sécuriser les cookies (https uniquement) par défaut dans les rails?

cookies[:foo] = "bar" 

et préciser que le drapeau "sécurisé" (https uniquement) soit comme ça:

cookies[:foo, :secure => true] = "bar" 

:secure est faux par défaut. Comment puis-je faire en sorte que les cookies soient sécurisés par défaut, à l'échelle de l'application?

Ceci est on Rails 2.3.8

Répondre

4

Merci @knx, vous me avez envoyé faire wn le bon chemin. Voici le monkey-patch je suis venu avec, ce qui semble fonctionner:

class ActionController::Response 
    def set_cookie_with_security(key, value) 
    value = { :value => value } if Hash != value.class 
    value[:secure] = true 
    set_cookie_without_security(key, value) 
    end 
    alias_method_chain :set_cookie, :security 
end 

Que pensez-vous?

+0

John, où dans l'application Rails plaçons-nous la classe ci-dessus? – Rafael

+2

dans un initialiseur –

+0

génial. Je vous remercie. une chose de plus, je dev mon env - en utilisant webrick - quand j'ai mis le drapeau de sécurité à true dans environment.rb je ne peux pas passer mon écran de connexion - j'ai remarqué qu'il y a cookie d'application dans les réponses. une idée de ce qui pourrait aller un? – Rafael

1

Solution rapide et sale: Je pense qu'il est possible en modifiant [] = méthode dans le module cookies pack d'action (actionpack/lib/action_controller/cookies.rb)

de:

def []=(name, options) 
     if options.is_a?(Hash) 
     options = options.inject({}) { |options, pair| options[pair.first.to_s] = pair.last; options } 
     options["name"] = name.to_s 
     else 
     options = { "name" => name.to_s, "value" => options } 
     end 

     set_cookie(options) 
    end 

à:

def []=(name, options) 
     if options.is_a?(Hash) 
     options.merge!({:secure => true}) 
     options = options.inject({}) { |options, pair| options[pair.first.to_s] = pair.last; options } 
     options["name"] = name.to_s 
     else 
     options = { "name" => name.to_s, "value" => options } 
     end 

     set_cookie(options) 
    end 
14

à partir de rails 3.1, selon the rails security guide, vous pouvez simplement définir les paramètres suivants dans votre application.rb:

config.force_ssl = true 

cela force le cookie à envoyer sur https uniquement (et je suppose que tout le reste aussi).

0
# session only available over HTTPS 
ActionController::Base.session_options[:secure] = true 
+0

est-ce une nouvelle fonctionnalité dans les rails 4? –

+0

Je ne sais pas. Cependant, dans Rails 4, cela fonctionne. Vous pouvez également vérifier cette propriété dans VOTRE version de Rails. – alsotang

+0

Ceci est pour le cookie de session seulement, non? Pas pour les cookies en général? –

27

Il n'y a pas besoin de ActionController monkey-patch/ActionDispatch et force_ssl a des effets secondaires (par exemple lorsque behind an ELB).

La façon la plus simple pour obtenir des cookies sécurisés est de modifier config/initializers/session_store.rb:

MyApp::Application.config.session_store :cookie_store, key: '_my_app_session', 
                 secure: Rails.env.production? 
+3

C'est la bonne réponse (vérifié que cela fonctionne dans Rails 4.2.7.1). Pour tester cela facilement, définissez 'secure: true' et vous pouvez vérifier que le cookie est généré correctement. Ensuite, vous pouvez le changer à 'Rails.env.production?' – PlagueHammer

+0

il semble que cela n'affectera que le cookie de session. La personne demandeuse a demandé la sécurité par défaut pour tous les cookies. Can @ david-cain peut-il vérifier si cette solution fonctionne pour tous les cookies? –

0

Vous devriez regarder le bijou porte-ssl-enforcer. Je cherchais simplement une réponse claire à cette question et cela résout le problème indépendamment de la version de Rails que vous utilisez, et c'est extrêmement configurable.

Questions connexes