Open FossPrime opened 1 year ago
As far as I know there is no way to revoke the token in a pure stateless authentication as the token itself is the sole source of truth, and any revocation mechanism of tokens is currently not really standardized in OAuth (see https://datatracker.ietf.org/doc/html/rfc7009#section-3). So maybe you could more detail what you are thinking about with this revokedAt
field ?
I wonder as well if this issue should not be directly posted to feathers authentication package as authentication management is not responsible of issuing or validating tokens. Notably, although Single Logout is a feature you'd like to have with token revocation, it's also a feature by itself, not directly related to revocation.
Authentication-management handles changing the password during password resets. revokeJWTHook could be an after hook on the authentication service that blocks logging-in with JWT's created before revokedAt timestamp.
I think it's more general as I could want to revoke tokens event without changing the user password, think about the case of users connected by OAuth or if I don't want to rely on the fact the user changes his password to ensure security. So for me these hooks could be at feathers authentication level as well to be used in others operations.
Sorry, but it's not yet clear what is the mechanism you'd like. The revokedAt
field should be set on the user so that all tokens generated prior to it should be considered invalid ?
The easiest way to revoke tokens instantaneously is to change the secret used to generate it or some built-in fields like the issuer. So maybe we should use the encrypted password of the user to generate his tokens so that when changing the password they automatically become invalid. I am not an authentication expert so I wonder if it could be possible to generate/validate tokens with such a dynamic behaviour.
We can easily regenerate the bcrypt salt... as long as we have the user's password. We can't invalidate JWT's with salting or a revokation array without incurring a performance penalty before the call to the User service.
If we use revokedAt as a userField in the user service, it would be extremely cheap to revoke whenever OAuth/SAML, if the user asks us to, or if fishy behavior is detected.
revokeJWTHook could be an after hook on the authentication service that blocks logging-in with JWT's created before revokedAt timestamp.
Do you want to revoke an issued JWT? There is an example in the Feathers cookbook: https://feathersjs.com/cookbook/authentication/revoke-jwt.html
Or do you want to disable the login/authentication for a user in general? In that case I agree with @claustres that such a function should be implemented as an extension of the authentication service and not of this package. We do something similar with an after hook in the authentication service, where we check user.isActive
and throw an authentication error if false.
Having a revokedAt field would allows to cheaply invalidate existing JWT tokens.
Steps to reproduce
Expected behavior
Attacker should not be able to log in.
Actual behavior
JWT cookie will still be valid. So would the socketio reconnection key. Allowing the attacker to login to your account, despite having changed your password.
Context
I use SAML where cascading logouts are a core feature. You should be able to logout once, and have all your SAML apps be disconnected remotely.