Rails 4 currently allows sessions to be signed and/or encrypted which is great.
ActionPack relies on EncryptedCookieJar which itself relies on ActiveSupport::MessageEncryptor
Here is the current constructor:
class EncryptedCookieJar #:nodoc:
def initialize(parent_jar, key_generator, options = {})
if ActiveSupport::LegacyKeyGenerator === key_generator
raise "You didn't set config.secret_key_base, which is required for this cookie jar. " +
"Read the upgrade documentation to learn more about this new config option."
end
@parent_jar = parent_jar
@options = options
secret = key_generator.generate_key(@options[:encrypted_cookie_salt])
sign_secret = key_generator.generate_key(@options[:encrypted_signed_cookie_salt])
@encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret)
end
The encryptor can accept a serializer, if a serializer isn't passed, then Marshal is used.
class MessageEncryptor
def initialize(secret, *signature_key_or_options)
options = signature_key_or_options.extract_options!
sign_secret = signature_key_or_options.first
@secret = secret
@sign_secret = sign_secret
@cipher = options[:cipher] || 'aes-256-cbc'
@verifier = MessageVerifier.new(@sign_secret || @secret, :serializer => NullSerializer)
@serializer = options[:serializer] || Marshal
end
The serializer is used to load/dump the session content.
I understand that we can't easily change the default serializer for historic reasons, but I would like to be able to use my own serializer (json, messagepack or whatever).
There are a few reasons for that, one mentioned by @tarcieri is security reason.
If the secret is leaked, the attacker can potentially execute ruby code on the server.
The second is to share the session across apps written in a different language.
Changing the serializer would obviously not guarantee that you can shove just whatever you want in the session like you currently can do with Marshal. Dumping the session object using a more strict serializer would potentially result in exceptions if the data format isn't supported and that's totally fine, actually I would like that.
I'm not asking to change the default, just to have a way to set my own serializer and deal with the consequences of my own choices. In other words, I'd like to be able to have a high level config flag to set the session serializer.
Others before me faced the same problem and monkey patched Rails: https://gist.github.com/jeffyip/4091166
I think an option would be a cleaner and safer alternative.
What do you think?
Rails 4 currently allows sessions to be signed and/or encrypted which is great.
ActionPackrelies onEncryptedCookieJarwhich itself relies onActiveSupport::MessageEncryptorHere is the current constructor:
The encryptor can accept a serializer, if a serializer isn't passed, then
Marshalis used.The serializer is used to load/dump the session content.
I understand that we can't easily change the default serializer for historic reasons, but I would like to be able to use my own serializer (json, messagepack or whatever).
There are a few reasons for that, one mentioned by @tarcieri is security reason.
If the secret is leaked, the attacker can potentially execute ruby code on the server.
The second is to share the session across apps written in a different language.
Changing the serializer would obviously not guarantee that you can shove just whatever you want in the session like you currently can do with
Marshal. Dumping the session object using a more strict serializer would potentially result in exceptions if the data format isn't supported and that's totally fine, actually I would like that.I'm not asking to change the default, just to have a way to set my own serializer and deal with the consequences of my own choices. In other words, I'd like to be able to have a high level config flag to set the session serializer.
Others before me faced the same problem and monkey patched Rails: https://gist.github.com/jeffyip/4091166
I think an option would be a cleaner and safer alternative.
What do you think?