-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to ensure TOTP is one-time in a distributed system. #69
Comments
Yes, all nodes will generate the same TOTP when given the same configuration. Make sure to also synchronize the system clock.
In contrary to the name, OTP's are not only valid for one time. They are valid for the time window they are generated in +- delay window. Otherwise a user could only sign in once every X seconds. The time window only ensures that when a token is compromised, the attacker only has the token period (30 seconds by default) + delay window (default 0) to coordinate a sign in attempt. This means that all replica nodes should accept all TOTP's in a valid window, even when the token was already used. The library has no knowledge of used tokens. |
Hi, thank you for the quick reply. I do believe that the one-time requirement is part of the RFC, see section 5.2,
As such Hazelcast/Redis or other similar solution seems necessary to me. Maybe you could consider as an improvement the possibility for your library to allow users to implement an interface to tell whether the OTP was already used or not. Thank you. |
You are absolutely correct, I must have missed that :). A pluggable system is a valid option. As you said, there are many ways the developer could make sure a token is only used once. I would rather not implement many different strategies for different stores in order to not bloat the library, but one default (in-memory) implementation could be useful. The user could switch strategies when necessary. Maybe developing multiple companion libraries for different strategies (Redis / Hazelcast) would be the way to go in order to not depend on external libraries for strategies you don't use. I do accept PR's so if you have the time to think with me / open a PR, it will be appreciated! |
In this case you need something like key manager. you can use an interface or an abstraction layer that provides a consistent interface for interacting with the key manager. Maybe database or 3rd party key manager, anh should have a in-memory manager as default. |
The RFC suggests a delayWindow of 1 or 2 to allow for time drift. This means that at any one moment 3 or 5 tokens are valid. But given that the time drift between the user and server does not change wildly, we only need to store the actually used |
Consider a clustered RESTful application that generates and validates TOTP using this library.
Is it sufficient to use the same seed across all replicas of the application in order to produce a TOTP that would be validated by any other replica node? In other words, is it safe to assume that each replica node, given the same configuration, should produce the same TOTP and should be able to validate the TOTP produced by any other node?
If the above is true, how to deal with the fact that once the OTP is used on one node, being it a one-time password, no other replica node should accept it?
Is this something users would need to build on top of the library? How about defining a pluggable strategy that would allow your users to store the generated TOTP in a shared storage, for example a self-expiring distributed cache based on hazelcast? If a used token was stored in a shared map (user -> token) until it expires and is removed, no other node would be able to use it.
The text was updated successfully, but these errors were encountered: