Class: Rack::Protection::EncryptedCookie
- Inherits:
-
Session::Abstract::Persisted
- Object
- Session::Abstract::Persisted
- Rack::Protection::EncryptedCookie
- Defined in:
- lib/rack/protection/encrypted_cookie.rb
Overview
Rack::Protection::EncryptedCookie provides simple cookie based session management. By default, the session is a Ruby Hash stored as base64 encoded marshalled data set to :key (default: rack.session). The object that encodes the session data is configurable and must respond to encode
and decode
. Both methods must take a string and return a string.
When the secret key is set, cookie data is checked for data integrity. The old_secret key is also accepted and allows graceful secret rotation. A legacy_hmac_secret is also accepted and is used to upgrade existing sessions to the new encryption scheme.
There is also a legacy_hmac_coder option which can be set if a non-default coder was used for legacy session cookies.
Example:
use Rack::Protection::EncryptedCookie,
:key => 'rack.session',
:domain => 'foo.com',
:path => '/',
:expire_after => 2592000,
:secret => 'change_me',
:old_secret => 'old_secret'
All parameters are optional.
Example using legacy HMAC options
Rack::Protection:EncryptedCookie.new(application, {
# The secret used for legacy HMAC cookies
legacy_hmac_secret: 'legacy secret',
# legacy_hmac_coder will default to Rack::Protection::EncryptedCookie::Base64::Marshal
legacy_hmac_coder: Rack::Protection::EncryptedCookie::Identity.new,
# legacy_hmac will default to OpenSSL::Digest::SHA1
legacy_hmac: OpenSSL::Digest::SHA256
})
Example of a cookie with no encoding:
Rack::Protection::EncryptedCookie.new(application, {
:coder => Rack::Protection::EncryptedCookie::Identity.new
})
Example of a cookie with custom encoding:
Rack::Protection::EncryptedCookie.new(application, {
:coder => Class.new {
def encode(str); str.reverse; end
def decode(str); str.reverse; end
}.new
})
Defined Under Namespace
Classes: Base64, Identity, Marshal
Instance Attribute Summary collapse
-
#coder ⇒ Object
readonly
Returns the value of attribute coder.
Instance Method Summary collapse
-
#initialize(app, options = {}) ⇒ EncryptedCookie
constructor
A new instance of EncryptedCookie.
Constructor Details
#initialize(app, options = {}) ⇒ EncryptedCookie
Returns a new instance of EncryptedCookie.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/rack/protection/encrypted_cookie.rb', line 143 def initialize(app, = {}) # Assume keys are hex strings and convert them to raw byte strings for # actual key material @secrets = .values_at(:secret, :old_secret).compact.map do |secret| [secret].pack('H*') end warn <<-MSG unless secure?() SECURITY WARNING: No secret option provided to Rack::Protection::EncryptedCookie. This poses a security threat. It is strongly recommended that you provide a secret to prevent exploits that may be possible from crafted cookies. This will not be supported in future versions of Rack, and future versions will even invalidate your existing user cookies. Called from: #{caller[0]}. MSG warn <<-MSG if @secrets.first && @secrets.first.length < 32 SECURITY WARNING: Your secret is not long enough. It must be at least 32 bytes long and securely random. To generate such a key for use you can run the following command: ruby -rsecurerandom -e 'p SecureRandom.hex(32)' Called from: #{caller[0]}. MSG if .key?(:legacy_hmac_secret) @legacy_hmac = .fetch(:legacy_hmac, OpenSSL::Digest::SHA1) # Multiply the :digest_length: by 2 because this value is the length of # the digest in bytes but session digest strings are encoded as hex # strings @legacy_hmac_length = @legacy_hmac.new.digest_length * 2 @legacy_hmac_secret = [:legacy_hmac_secret] @legacy_hmac_coder = ([:legacy_hmac_coder] ||= Base64::Marshal.new) else @legacy_hmac = false end # If encryption is used we can just use a default Marshal encoder # without Base64 encoding the results. # # If no encryption is used, rely on the previous default (Base64::Marshal) @coder = ([:coder] ||= (@secrets.any? ? Marshal.new : Base64::Marshal.new)) super(app, .merge!(cookie_only: true)) end |
Instance Attribute Details
#coder ⇒ Object (readonly)
Returns the value of attribute coder.
141 142 143 |
# File 'lib/rack/protection/encrypted_cookie.rb', line 141 def coder @coder end |