Railsコントローラでは、次のようにCookieを設定できます:
cookies[:foo] = "bar"
そして、「セキュア」(httpsのみ)フラグが次のようにオンになるように指定します。
cookies[:foo, :secure => true] = "bar"
:secure
はデフォルトでfalseです。デフォルトで、アプリケーション全体でCookieを安全にするにはどうすればよいですか?
これはRails 2.3.8です。
@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
どう思いますか?
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、 the Rails security guide によると、次のようにapplication.rb
:
config.force_ssl = true
これにより、Cookieはhttps経由でのみ送信されます(他のすべても想定しています)。
# session only available over HTTPS
ActionController::Base.session_options[:secure] = true
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
Rack-ssl-enforcer gemを確認する必要があります。私はこれに対する明確な答えを探していましたが、どのバージョンのRailsを使用しているかに関係なく、問題を解決し、さらに非常に構成可能です。