Skip to content

Can't change the default session serializer (Marshal) #12881

Description

@mattetti

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions