代码之家  ›  专栏  ›  技术社区  ›  John Bachir

如何在rails中使cookies默认安全(仅限https)?

  •  31
  • John Bachir  · 技术社区  · 15 年前

    cookies[:foo] = "bar"
    

    并指定“secure”(仅限https)标志如下所示:

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

    :secure

    这是在Rails 2.3.8上

    7 回复  |  直到 5 年前
        1
  •  44
  •   Jared Beck    4 年前

    没有必要用monkeypatch ActionController / ActionDispatch ,和 force_ssl 有副作用(例如 behind an ELB ).

    config/initializers/session_store.rb :

    MyApp::Application.config.session_store( 
      :cookie_store, 
      key: '_my_app_session',
      secure: Rails.env.production?
    )
    
        2
  •  18
  •   Markus    12 年前

    从rails 3.1开始,根据 the rails security guide application.rb

    config.force_ssl = true
    

    这迫使cookie只能通过https发送(我也假设其他所有内容)。

        3
  •  4
  •   John Bachir    13 年前

    谢谢@knx,你让我走上了正确的道路。这是我想出的monkeypatch,它似乎起作用了:

    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
    

    你怎么认为?

        4
  •  2
  •   Imran Ahmad    6 年前

    应用程序,在您的环境文件中启用force\u ssl,例如 生产.rb.

    # config/environments/production.rb
    config.force_ssl = true
    

    应用程序,为应用程序设置安全cookie标志,以便 会话Cookie仅通过HTTPS发送。

    其结果是您不能再通过HTTP维护会话状态,但至少可以保护自己免受会话劫持攻击。

    # config/initializers/session_store.rb
    # set secure: true, optionally only do this for certain Rails environments (e.g., Staging / Production
    Rails.application.config.session_store :cookie_store, key: '_testapp_session', secure: true
    

    Here 视频教程是一样的。

        5
  •  1
  •   knx    15 年前

    快速而肮脏的解决方案:我认为可以通过修改actionpackcookies模块(actionpack/lib/action\u controller)中的[]=method来实现/饼干.rb)

        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
    
        6
  •  1
  •   Radim Köhler user2134822    11 年前
    # session only available over HTTPS
    ActionController::Base.session_options[:secure] = true
    
        7
  •  0
  •   brightball    9 年前

    您应该看看rack ssl enforcer gem。我只是在寻找一个干净的答案,它解决了这个问题独立于哪个版本的Rails,而且它是非常可配置的。

        8
  •  0
  •   K M Rakibul Islam    5 年前

    您可以按照上面的一些答案(使用 secure 中的选项 config/initializers/session_store.rb 文件):

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

    它将只保护会话cookie,但其他cookie将不安全。

    secure_headers 宝石。只需添加 secure_headers 把宝石放进你的宝石档案里, bundle install 宝石和创造 config/initializers/secure_headers.rb

    SecureHeaders::Configuration.default do |config|
      config.cookies = {
        secure: true, # mark all cookies as "Secure"
      }
    end
    

    您还可以添加这些建议的配置并设置 httponly samesite 选项还有:

    SecureHeaders::Configuration.default do |config|
      config.cookies = {
        secure: true, # mark all cookies as "Secure"
        httponly: true, # mark all cookies as "HttpOnly"
        samesite: {
          lax: true # mark all cookies as SameSite=lax
        }
      }
    end