在 Rails 控制器中,我可以像这样设置 cookie:
cookies[:foo] = "bar"
并指定“安全”(仅限 https)标志是这样的:
cookies[:foo, :secure => true] = "bar"
:secure
默认为假。默认情况下,如何让 cookie 在应用程序范围内保持安全?
这是在 Rails 2.3.8 上
在 Rails 控制器中,我可以像这样设置 cookie:
cookies[:foo] = "bar"
并指定“安全”(仅限 https)标志是这样的:
cookies[:foo, :secure => true] = "bar"
:secure
默认为假。默认情况下,如何让 cookie 在应用程序范围内保持安全?
这是在 Rails 2.3.8 上
无需猴子补丁ActionController
/ ActionDispatch
,并且force_ssl
有副作用(例如,在 ELB 后面时)。
实现安全 cookie 的最直接方法是修改config/initializers/session_store.rb
:
MyApp::Application.config.session_store(
:cookie_store,
key: '_my_app_session',
secure: Rails.env.production?
)
从 rails 3.1 开始,根据rails security guide,您可以简单地在您的application.rb
:
config.force_ssl = true
这会强制 cookie 仅通过 https 发送(我也假设其他所有内容)。
谢谢@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
你怎么看?
要强制 SSL 并为整个 Ruby on Rails 应用程序启用安全 cookie,请在您的环境文件(例如 production.rb)中启用 force_ssl。
# config/environments/production.rb
config.force_ssl = true
如果您的 Ruby on Rails 应用程序需要支持 HTTP 和 HTTPS 流量,请为您的应用程序设置安全 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
这是相同的视频教程。
快速而肮脏的解决方案:我认为可以通过修改动作包 cookie 模块中的 []= 方法(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
# session only available over HTTPS
ActionController::Base.session_options[:secure] = true
您应该查看 rack-ssl-enforcer gem。我只是在寻找一个干净的答案,它解决了与您使用的 Rails 版本无关的问题,而且它非常可配置。
您可以按照上述某些答案中的说明执行此操作(使用文件secure
中的选项config/initializers/session_store.rb
):
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、bundle install
gem 并创建一个config/initializers/secure_headers.rb
包含以下内容的文件:
SecureHeaders::Configuration.default do |config|
config.cookies = {
secure: true, # mark all cookies as "Secure"
}
end
默认情况下,这将使 Rails 应用程序中的所有 cookie 安全。
您还可以添加这些推荐的配置并设置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