The "rememberable" Devise strategy is used to re-authenticate a user from the value stored in a persistent cookie (the remember_user_token
that you decoded) with the following format:
[[<user_id>], "<user_salt>", "<cookie_generated_at_UTC_time>"]]
The cookie is signed to prevent tampering of the cookie values (the signature is the blob you can find after the "--" in the cookie).
The application you are testing uses the default implementation of "rememberable", which does away with the need of having a database column to store the per-user "remember tokens"; instead it uses the user id + password salt as the key to uniquely identify the user. When the application receives back the signed id+salt
cookie, it looks up a user with the matching id
and if the salt
matches that of the cookie, it successfully authenticates the user and continues the processing.
The use of the salt as unique identifier avoids having to store "remember tokens" on the server side; as a trade-off it reveals the salt. Giving an attacker access to the bcrypt salt without the actual hashed password is useless (the salt is only used to avoid pre-computed hash attacks, forcing an attacker to bruteforce each hashed secret separately). If an attacker gains access to the user password they will also get access to the salt, so the security of the "rememberable" strategy is not compromised by the sharing the salt.
I would personally be more concerned by the sharing of the user ID (the first field in the cookie), e.g. it may be later re-used in direct object reference attacks.
If you are not comfortable exposing the user password salt you can implement your own remember_token
method in your Devise user class, see the rememberable model, e.g. for instance creating random tokens and storing them on the user database table.