Make #4094 an opt-in config until we can swap it to opt-out in the next major release
While niche, the casing algo change will require existing tooling change outside of CouchDB. As such, I think we should consider this a breaking change as per SemVer and I suggest we make this an opt-in config for 3.x and an opt-out config for 4.x.
I don't believe we made any promises about the AuthSession cookie format. It's an opaque string generated by CouchDB that CouchDB can validate when it is presented again later.
An upgrade note seems sufficient to me.
what about auth proxies? the token is a part of our documented public API
Can we do for proxy auth something like that:
- Calc TokenSHA256
- Test X-Auth-CouchDB-Token == TokenSHA256 2.1 True -> continue 2.2 False -> Calc TokenSHA1 2.2.1 Test X-Auth-CouchDB-Token == TokenSHA1 2.2.1.1 True -> continue 2.2.1.2 False -> Error
that would be an option, but you’d want admins to disable the sha1 check completely still, so I’m not sure we can get around a config option
hrm, that is annoying, but fair point.
I suggest that the digest function underneath the two uses of HMAC be a configuration item then, defaulting to sha256 in the next release. We should allow any value that is supported by erlang.
I think another issue with this change is that it breaks cookie auth for rolling upgrades since a cookie issued by a sha1 node won't be readable by a sha256 node and vice versa. It would be great if we could add some kind of backward compatibility so that rolling upgrades continue to work.
the config proposal would appear to achieve it? upgrade all the nodes first then config:set to the new algorithm on all nodes afterward.
+1 for the config option
the config proposal would appear to achieve it? upgrade all the nodes first then config:set to the new algorithm on all nodes afterward.
In this scenario would not cookies encoded with e.g. sha1 fail on a newly reconfigured sha256 node?
In Cloudant's implementation of IAM auth (primarily written by Bob) exists an implementation of IAM session cookies, which are similar to regular session cookies, except that they use IAM access tokens to generate the payload.
When the format of the cookie needed to change due to changed requirements for items being hashed, we wrote code that supported both the old payload (for existing cookies) and the new payload for cookies created henceforth.
Would there be an objection to using a similar algorithm for upgrading between sha1 and sha256 here?
Would there be an objection to using a similar algorithm for upgrading between sha1 and sha256 here?
given that the fallback for an invalid session is re-login, just like after a session timeout, I don’t see a huge benefit of falling back to sha1.
that's right, Jay, users would have to login again when the config item is flipped, but that seems right to me when enhancing security. otherwise we'd have to add some new code to only allow hmac-sha1 cookies for some period of time (as session cookies are auto-extended through active use). Having noted that I think it is past time we looked at the authn/authz layer. I'd much prefer session cookies not to extend and put the onus on the client to renew pre-emptively.
Maybe we should Perhaps we should make an explicit distinction here again.
Originally in my PR #4094 I wanted to change the hash algorithm for cookie authentication only. When I changed it, I also changed it for proxy authentication (rather unintentionally).
For cookie authentication, I agree with Jan & Robert, Logout, Login and Done! My suggestion from above was a way that a user doesn't have to do anything to keep proxy auth working, but as Robert mentioned, it's a security hole or in 5 years this code is still in the code base (it's my gut feeling). The following questions are swirling around in my head:
- Should we revert the has algorithm only for proxy auth to use sha1 and keep sha256 for cookie auth?
- Do we really want to add a config switch for this reason and for this case? There are already many setting options (which has pros and cons), not all of which have ended up in the documentation (TODO for a next PR) - but that's an other discussion (perhaps a new configuration system with automatic deprecation of config options in X + 2 versions and its successors).
- Is it important that a user can choose an internal hash algorithm? If we allow hash algorithms that Erlang offers us, we will eventually face the problem again that the old configured option is not available in the new version.
otherwise we'd have to add some new code to only allow hmac-sha1 cookies for some period of time (as session cookies are auto-extended through active use).
I was considering this a general enough problem (since I've encountered it twice in under a year) for a cookie_upgrade behavior to be written and then specific implementations used for various upgrade paths, to ensure a seamless end user experience. However, I can also see the big benefit to not adding complicated fallback code to security pathways in order to just to keep it simple (in much the same way we should probably remove the code that automatically extends cookie lifetimes).
So, given that there appears to be little stomach for the above feature, I'm fine with a config option, especially if it continues to default to sha1 so that no incompatibilities are introduced. We could change that to sha256 for a major release.
My preference would be to revert https://github.com/apache/couchdb/pull/4094 for now, until a configurable version can be reviewed, since I'm on the hook to create a release with this code, and would love to not have to use a fork.
How about this;
- when we receive an AuthSession cookie we try to confirm it with HMAC-SHA256. If that is successful, we continue as usual.
- if unsuccessful we try to confirm it with HMAC-SHA1. If that is successful, we consider it expired and send a new one (which is HMAC-SHA256)
- an administrator can disable the fallback option. it is enabled by default in the first release and disabled by default in the release after that.
That is, after we merge this work couchdb only issues new HMAC-SHA256 cookies but will accept (and upgrade) SHA1's if the administrator allows.
That sounds pretty good, Bob. I would suggest making the code general enough so that it can also be used for upgrading to sha512 (or whatever) in a few years.
And can we pretty please revert https://github.com/apache/couchdb/pull/4094 while we work on your proposal?
@big-r81 what do you think about reverting while we redo this with compatibility improvements?
@rnewson yes, let’s make it better! +1 for reverting!
Hi,
i would like to continue the work on this topic. Some questions arise while thinking about this. I would like to do this:
- Introduce multiple config options in default.ini:
; Set the HMAC algorithm used by cookie and proxy authentication
; Possible values: sha,sha224,sha256,sha384,sha512,sha3_224,sha3_256,sha3_384,sha3_512,
; blake2b,blake2s,md4,md5,ripemd160
; Default: sha256
;hmac_algorithm = sha256
; The following algorithms are blacklisted and can't be used for the hash
; Default: [sha,md4,md5]
;hmac_algorithm_blacklist = [sha,md4,md5]
; If hmac_algorithm_use_legacy_sha = true then sha (sha1) is used for HMAC. It defaults to
; true in 3.x for BC-compatability and gets removed in 4.x. Setting this will override the
; used hash algorithm in hmac_algorithm and ignores the blacklisted sha value in
; hmac_algorithm_blacklist. If set to false, then the hash algorithm set by hash_algorithm
; is used.
hmac_algorithm_use_legacy_sha = true
So a user could switch explicitly to a new hash algorithm, but the default behavior remains as it is right now. If we get consensus about this. I would open a PR.
My next question is, if we want to add code for internal upgrade of AuthSession to SHA256 like Bob suggest?
A user can explicitly use new hash algorithms if hmac_algorithm_use_legacy_sha is set to false.
How about this;
1. when we receive an AuthSession cookie we try to confirm it with HMAC-SHA256. If that is successful, we continue as usual. 2. if unsuccessful we try to confirm it with HMAC-SHA1. If that is successful, we consider it expired and send a new one (which is HMAC-SHA256) 3. an administrator can disable the fallback option. it is enabled by default in the first release and disabled by default in the release after that.That is, after we merge this work couchdb only issues new HMAC-SHA256 cookies but will accept (and upgrade) SHA1's if the administrator allows.
I suggest keeping it simple for the first version. You only need a 'legacy' toggle option, defaulting to true as you have it above. CouchDB, after upgrade, will use HMAC-SHA-256 for new cookies, but optionally accept HMAC-SHA-1 signed cookies (and return a new HMAC-SHA-256 cookie of original expiration).
I was considering a list of acceptable cookie hash algorithms in a single config variable, where the first element of the list is the preferred hash, while the others are still acceptable. In our current situation, where we want to be backward compatible with sha1, but want to only create new cookies with sha256, the config option would look like this:
[chttpd_auth]
cookie_hash_algorithms = sha256, sha1 ; new uses first element, others can be decoded
This seems fairly simple, and extensible for the next time we need to upgrade, without any additional code changes.
Closing this, implemented with #4140.