You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So CryptoJS just dropped a bomb: everything they do by default is not as
strong as it could be. Oh and by the way, the entire library is now
deprecated. :(
GHSA-xwcq-pm8m-c4vf
Unfortunately we can't just upgrade to the latest release 4.2.0 because
the hashing algorithm has changed, and a user would no longer be able to
login: the default hash generated by CryptoJS 4.2.0 won't match the hash
generated by CryptoJS 4.1.0.
Note that this is only an issue if someone got the contents of your
database and wanted to figure out user passwords (but it still cost
[$45,000 per password](https://eprint.iacr.org/2020/014.pdf)
apparently?).
In the wake of this CVE we're going to convert dbAuth to use the
built-in `node:crypto` library instead, with more sensible default
configuration.
There are two areas where we use the crypto libs:
1. Hashing the user's password to store in the DB and compare on login
2. Encrypting/decrypting the session data in a cookie
We're going to do this in a non-breaking way by supporting *both* the
original CryptoJS-derived values, and the new `node:crypto` ones. The
alternative would be to require every user to change their password,
which seems like a non-starter.
1. On signup, store the hashedPassword using the new `node:crypto`
algorithm
2. On login, compare the user's hashedPassword using the `node:crypto`
algorithm:
* If a match is found, user is logged in
* If a match fails, fall back to the original CryptoJS algorithm (but
using the `node:crypto` implementation)
* If a match is found, update the `hashedPassword` in the database to
the new algorithm, user is logged in
* If a match is still not found, the user entered the wrong password.
Likewise for cookies and login:
1. When encrypting the user's session, always use the new `node:crypto`
algorithm
2. When decrypting the user's session, first try with `node:crypto`
* If decrypting works, user is logged in
* If decrypting fails, try the older CryptoJS algorithm ([I haven't
figured how](brix/crypto-js#468) to use
`node:crypto` to decrypt something that was encrypted with CryptoJS yet,
so we'll need to keep the dependency on CryptoJS around for now)
* If decrypting works, re-encrypt the cookie using the new `node:crypto`
algorithm, user is logged in
* If decrypting still fails, the session is invalid (someone tampered
with the cookie) so log them out
We could announce in the Release Notes that if a platform wants the
absolute safest route, they should change their `SESSION_SECRET` *and*
have users change their password if, for example, they suspect that
their database may have been compromised before our release.
The next most secure thing would be to just change `SESSION_SECRET`
which would log everyone out, and on next login their password will get
re-hashed with the new algorithm.
But the default for most people will probably be to just go about
business as usual, and as time goes by more and more users' passwords
will be re-hashed on login.
Related to #9337#9338#9339#9340
---------
Co-authored-by: Dominic Saadi <[email protected]>
// TODO: this needs to go into graphql somewhere so that each request makes
1410
-
// a new CSRF token and sets it in both the encrypted session and the
1411
-
// csrf-token header
1451
+
// TODO: this needs to go into graphql somewhere so that each request makes a new CSRF token and sets it in both the encrypted session and the csrf-token header
0 commit comments