如何在 Rails 中默认确保 cookie 安全(仅限 https)?

发布于 2024-09-24 12:46:41 字数 282 浏览 4 评论 0原文

在 Rails 控制器中,我可以像这样设置 cookie:

cookies[:foo] = "bar"

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

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

:secure 默认情况下为 false。如何让 cookie 在应用程序范围内默认是安全的?

这是在 Rails 2.3.8 上

In a Rails controller, I can set a cookie like this:

cookies[:foo] = "bar"

And specify that the "secure" (https-only) flag be on like this:

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

:secure is false by default. How can I have cookies be secure by default, application-wide?

This is on Rails 2.3.8

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

北风几吹夏 2024-10-01 12:46:42

谢谢@knx,你让我走上了正确的道路。这是我想出的猴子补丁,它似乎有效:

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

你觉得怎么样?

Thanks @knx, you sent me down the right path. Here's the monkeypatch I came up with, which seems to be working:

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

What do you think?

缪败 2024-10-01 12:46:42

快速而肮脏的解决方案:我认为可以通过将action pack cookies模块(actionpack/lib/action_controller/cookies.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

Quick and dirty solution: i think it is possible by modifying []= method in action pack cookies module (actionpack/lib/action_controller/cookies.rb)

from:

    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

to:

    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
李不 2024-10-01 12:46:42
# session only available over HTTPS
ActionController::Base.session_options[:secure] = true
# session only available over HTTPS
ActionController::Base.session_options[:secure] = true
狼性发作 2024-10-01 12:46:42

您应该查看rack-ssl-enforcer gem。我只是在寻找一个干净的答案,它解决了与你使用哪个版本的 Rails 无关的问题,而且它的可配置性非常好。

You should look at the rack-ssl-enforcer gem. I was just looking for a clean answer to this and it solves the problem independent of which version of Rails you're on, plus it's extremely configurable.

心的位置 2024-10-01 12:46:42

您可以按照上述一些答案中提到的方式执行此操作(使用 config/initializers/session_store.rb 文件中的 secure 选项):

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

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

如果您想默认保护 Rails 应用中的所有 cookie,您可以使用 secure_headers gem。只需将 secure_headers gem 添加到您的 Gemfile,捆绑安装 gem 并创建一个包含以下内容的 config/initializers/secure_headers.rb 文件

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

:默认情况下,您的 Rails 应用程序中的所有 cookie 都会受到保护。

您还可以添加这些推荐配置并设置 httponlysamesite 选项:

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

You can do this as mentioned in some of the above answers (use secure option in the config/initializers/session_store.rb file):

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

which will only secure the session cookie, but other cookies will not be secure.

If you want to secure all the cookies in your Rails app by default, you can use the secure_headers gem. Just add the secure_headers gem to your Gemfile, bundle install the gem and create a config/initializers/secure_headers.rb file with this content:

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

This will make all the cookies secure in your Rails app by default.

You can also add these recommended configurations and set the httponly and samesite options as well:

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
心碎无痕… 2024-10-01 12:46:41

没有必要对 ActionController/ActionDispatch 进行 Monkeypatch,并且 force_ssl 有副作用(例如,当 位于 ELB 后面)。

实现安全cookie的最直接方法是修改config/initializers/session_store.rb

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

There's no need to monkeypatch ActionController/ActionDispatch, and force_ssl has side effects (e.g. when behind an ELB).

The most straightforward way to achieve secure cookies is to modify config/initializers/session_store.rb:

MyApp::Application.config.session_store( 
  :cookie_store, 
  key: '_my_app_session',
  secure: Rails.env.production?
)
雪化雨蝶 2024-10-01 12:46:41

从rails 3.1开始,根据rails安全指南,您可以简单地设置在您的 application.rb 中遵循以下内容:

config.force_ssl = true

这会强制 cookie 仅通过 https 发送(我也假设其他所有内容)。

starting with rails 3.1, according to the rails security guide, you can simply set the following in your application.rb:

config.force_ssl = true

this forces the cookie to be sent over https only (and I assume everything else, too).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文