Rails 4.1 introduced JSON
serialization for cookies. Earlier
all the cookies were serialized using Marshal library of Ruby. The marshalling
of cookies can be
because of the possibility of remote code execution vulnerability. So the change
:json is welcoming.
The new applications created with Rails 4.1 or 4.2 have
:json as the default
rake rails:update used for upgrading existing Rails apps to new versions
rightly changes the serializer to
1Rails.application.config.action_dispatch.cookies_serializer = :json
However that change can introduce an issue in the application.
Consider a scenario where the cookies are being used for session storage. Like
many normal Rails apps, the
current_user_id is being stored into the session.
1session[:user_id] = current_user_id
Before Rails 4.1 the cookie will be handled by Marshal serializer.
1cookie = Marshal.dump(current_user_id) # 42 => "\x04\bi/" 2Marshal.load(cookie) # "\x04\bi/" => "42"
After the upgrade the application will try to unserialize cookies using
which were serialized using
1JSON.parse cookie # Earlier dumped using Marshal 2# JSON::ParserError: 757: unexpected token at i/'
So the deserialization of the existing cookies will fail and users will start getting errors.
Hybrid comes to rescue
To prevent this Rails provides with a
hybrid serializer. The
serializer deserializes marshalled cookies and stores them in JSON format for
the next use. All the new cookies will be serialized in the JSON format. This
gives happy path for migrating existing marshaled cookies to new Rails versions
like 4.1 and 4.2.
To use this hybrid serializer, set cookies_serializer config as
1Rails.application.config.action_dispatch.cookies_serializer = :hybrid
After this, all the existing marshalled cookies will be migrated to
format properly and in the future upgrade of Rails, you can safely change the
:json which is the default and safe value of this
Since this blog was published Rails has changed a bit. You might run into a few gotchas. Dylan has written about how to handle those gotchas here.