-
-
Save yemster/7916553 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Hack to change the Rails cookie serializer from Marshal to JSON and therefore allow the session | |
# to be shared between different languages but also avoid that someone knowing the | |
# cookie secret key could execute arbitrary code on the server by unmarshalling | |
# modified Ruby code added to the session/permanent cookie. | |
# | |
# Note that all users will beed to login again since both the remember me cookie and the session cookies | |
# won't be valid. Note also that the remember me cookie is tested multiple times per request even when it fails. | |
# for performance reasons you might want to delete it if these extra cycles are too costly for you. | |
# | |
# Rails 4 (not tested on Rails 3). | |
# Author: Matt Aimonetti / mattetti | |
# Rails issue (more info, discussion, updates): https://github.com/rails/rails/issues/12881 | |
# Wrapper module around `JSON` so we can rescue a parsing error | |
module JsonSessionSerializer | |
def self.load(value) | |
begin | |
JSON.parse(value) | |
rescue JSON::ParserError | |
nil | |
end | |
end | |
def self.dump(value) | |
JSON.generate(value) | |
end | |
end | |
# Make cookies use JSON as serializer instead of Marshal (Rails 4) | |
module ActionDispatch | |
class Cookies | |
# used by the remember me and other permanent cookies. | |
class SignedCookieJar #:nodoc: | |
include ChainedCookieJars | |
def initialize(parent_jar, key_generator, options = {}) | |
@parent_jar = parent_jar | |
@options = options | |
secret = key_generator.generate_key(@options[:signed_cookie_salt]) | |
# The only actual change is to pass a serializer options with a default set to our JSON serializer. | |
@verifier = ActiveSupport::MessageVerifier.new(secret, { serializer: options[:serializer] || JsonSessionSerializer }) | |
end | |
end | |
# used by the session cookie. | |
class EncryptedCookieJar #:nodoc: | |
include ChainedCookieJars | |
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]) | |
# The only actual change is to pass a serializer options with a default set to our JSON serializer. | |
@encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, { serializer: options[:serializer] || JsonSessionSerializer } ) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment