Skip to content

Comments

Default cipher for ActiveSupport::MessageEncryptor is too strong for JRuby#12256

Closed
BanzaiMan wants to merge 1 commit intorails:masterfrom
BanzaiMan:configurable_encrypted_cookie_jar_cipher
Closed

Default cipher for ActiveSupport::MessageEncryptor is too strong for JRuby#12256
BanzaiMan wants to merge 1 commit intorails:masterfrom
BanzaiMan:configurable_encrypted_cookie_jar_cipher

Conversation

@BanzaiMan
Copy link
Contributor

The default cipher for ActiveSupport::MessageEncryptor (aes-256-cbc) is too strong for JRuby without installing Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. While some users have figured out how this problem manifests, it is far from obvious how to solve this problem, and I would like to have a reasonable workaround.

A couple of possible solutions:

  1. Change the default with a smaller key size, say 'aes-128-cbc'. Given that there are applications in the wild which assume 'aes-256-cbc', this is probably not a good way to address this problem.
  2. Provide a means of specifying cipher for EncryptedCookieJar. Within Rails, EncryptedCookieJar appears to be the only thing that uses MessageEncryptor. If there is an option to specify a reasonable cipher, we can advise JRuby users to deal with the encryption strength effectively.

This PR aims to realize the latter approach.

@vipulnsward
Copy link
Member

👍 for the change.
This needs a test and a CHANGELOG

@rds13
Copy link

rds13 commented Sep 19, 2013

+1

@tenderlove
Copy link
Member

Seems fine to me. Can you rebase? /cc @NZKoz

@NZKoz
Copy link
Member

NZKoz commented Sep 22, 2013

I don't see where you specify the default as aes-256-cbc? We can't change that without breaking people's apps in a weird and completely unintelligible way.

@tenderlove
Copy link
Member

@NZKoz it's not very intuitive, but we already have a nil check for the cipher type here. So if it isn't set in the cookie jar, it will use the default. IMO, we should pass the default in rather than have the constructor determine it, but I think this is the smallest possible patch to add the feature.

EncryptedCookieJar uses ActiveSupport::MessageEncryptor, the default
cipher of which is 'aes-256-cbc'.
This cipher is too strong for the default JVM, so JRuby needs a means of
configuring the cipher to avoid the pesky OpenSSL::Cipher::CipherError.
@jeremy
Copy link
Member

jeremy commented Sep 22, 2013

Unless the encrypted message is tagged with its cipher, making this a config option is devilishly begging to give some unwitting devs an extremely bad day™ when they go to upgrade their app or switch from ruby to jruby and think twiddling this config "fixes the glitch" in their tests.

@BanzaiMan
Copy link
Contributor Author

Who would want to change the CookieJar cipher in an existing application? I am not a cryptography expert, but I'm pretty sure that it is Asking For Trouble®. They'd better have a good reason to do it than just eradicating annoying error messages.

What I ultimately want is a better out-of-the-box Rails experience for JRuby users. Hard-coding aes-256-cbc deep into Rails is the real problem. I don't know why it was chosen to be a hard-coded default in the first place; and maybe there was a good reason for this choice. At any rate, I feel that it is too late to change that. So I'm asking for what I feel is the next best thing. I am open for other suggestions I might have missed.

Currently, the ones who are affected by the issue are JRuby users who don't have JCE Unlimited Strength Jurisdiction Policy files installed. Those running MRI would not see that, because aes-256-cbc is supported.

When those running on MRI upgrades to a version of Rails supporting this configuration option, they would have no reason to believe that changing this configuration option would fix the problem. (I do not exclude the possibility that I'm being too naïve here.) When an existing Rails app is migrated to JRuby, the path of least resistance would be to continue using aes-256-cbc, which will be available by installing the policy file, or Unlimited Strength Crypto hack. (JRuby cannot make these changes for the user, for likely legal reasons.) I am not sure how we can anticipate that scenario and provide reasonable message to suggest the fix, but I guess we (JRuby community) would have to deal with that.

@NZKoz
Copy link
Member

NZKoz commented Sep 22, 2013

As for why aes 256 was chosen, I believe, though I could be remembering incorrectly, that I chose it based on [http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html](Colin Percival's cryptographic right answers).

AES256 has since had some attacks against it, but IIRC they're all related-key attacks which aren't of particular concern here where we generate the keys from random data. However I could be entirely mistaken, perhaps we should think of a way to migrate to another cipher.

I support the idea of improving the OOTB experience for JRuby users, however there are some issues allowing people to change the cipher. Specifically, if they choose a cipher which has a keysize > 64 bytes (not sure if openssl has any) then it will just fail with a strange error from Cipher#key=. Then, as @jeremy mentions, we don't tag ciphertexts in any way, making switching ciphers very difficult.

I'm not even sure we should tag ciphertexts as that would allow an attacker to select his own cipher and cause no-end of havoc inside your application without careful whitelisting and verification which I don't think we're ready to do.

Is perhaps the best bet to just rescue that error and point jruby users at a page saying "your JVM is crippled, download this magical thing that unlocks it"? Are there people who can't install this stuff? We require people to install ruby's openssl libraries.

@BanzaiMan
Copy link
Contributor Author

@NZKoz I understand the historical context better now. Thank you.

I am fine with rescuing the error (on JRuby specifically, if that is not too much of a code smell) and pointing to the resources I've indicated in my last comment.

@NZKoz
Copy link
Member

NZKoz commented Sep 22, 2013

How about we try to figure out a 'nice error message' situation, and see how usable the resulting situation is. But assuming there's no decent solution there we can re-examine something like an undocumented cipher setting so JRuby users could have a chance, but the rest of us wouldn't accidentally set it to something crazy?

@BanzaiMan
Copy link
Contributor Author

@NZKoz That sounds reasonable. Close this ticket at will unless you have a reason to keep it open.

Thanks.

@NZKoz
Copy link
Member

NZKoz commented Sep 22, 2013

I'm unclear with current closing/opening etiquette so I'll leave that decision to someone else, but just ping me once we have a pull request for the 'nice failure' option.

@BanzaiMan
Copy link
Contributor Author

I'm closing this one.

@BanzaiMan BanzaiMan closed this Sep 22, 2013
@BanzaiMan BanzaiMan deleted the configurable_encrypted_cookie_jar_cipher branch September 23, 2013 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants