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
Add brute force prevention #24
Comments
Good idea is to make it configurable to fit user's needs to balance between comfort and security |
How would that fit into the library? |
Yes, suggest to include this functionality as utility. It's important, because connected with main part of library and hard to implement correctly by new to cryptography users. This algorhytm isn't a part of TOTP RFC, it's self-engeneered. So if you found RFC or another standard it will be better to implement standard |
See 7.3 RFC 4226 And it's important to not zero timer on window change (also math magic) |
Time delay can be implemented by storing last time and fail count mapped by secret |
Section 7.2 of RFC 4226 is titled "Throttling at the Server". I completely agree that the server should have a throttling scheme of calling the OTP library, but the OTP library itself is just a utility that performs the correct calculations given some input. IMO, the throttling makes the most sense to be implemented by the server outside of the library so that it can take into account throttling on a per-user basis, etc. |
@conorgil Secret key throttling is universal and reliable. Not matter, one key used by many users or many keys used by one. If TOTP connected to one secret key can be bruteforced it's cracked |
@cyclopentan I think we are all in agreement that preventing brute force attacks is a critical part of implementing HOTP and TOTP correctly as part of an authentication protocol. I am just having a difficult time understanding the argument to put the throttling logic into the OTP lib. I just reread RFC 4226 - HOTP: An HMAC-Based One-Time Password Algorithm and a few things stood out to me.
It makes a distinction between the HOTP algorithm and the deployment of the algorithm (e.g. the application and protocols).
Here again it distinguishes between the HOTP algorithm and the inclusion of that algorithm in a larger application, specifically for use in an authentication protocol.
More details and recommendations on how to implement a protocol P that uses the HOTP algorithm. Notice that requirement 2 specifically mentions brute force attacks and actually only recommends it. I agree with you that it should be required, of course.
I reproduced section 7.3 in its entirety because it is directly relevant to this discussion. It seems to me that this section is recommending that the application, not the HOTP algorithm, is responsible for implementing one of the brute force attack prevention mechanisms: "the authentication server needs to detect and stop brute force attacks". The OTP library implements the HOTP algorithm, which is one important component of utilizing HOTP as part of an authentication protocol, but certainly not the only component. The rate limiting for brute force attacks needs to be contextual for each individual user of the system. Each user has a unique secret key, which should be rate limited individually as to not impact other users trying to authenticate to the system. It makes the most sense to me to have the OTP lib only be responsible for implementing the HOTP algorithm. This makes the scope small and easier to test. Other concerns of implementing a protocol P that uses HOTP should be left to the application developer to implement. For example, the application must store the counter C for each user, the secret K for each user, the max number of guesses T, the look-ahead window s, etc in the database. The application must also decide how to generate the secret keys (see section Please let me know if I am misunderstanding your position here. |
@conorgil thank you for high quality discussion. I am impressed in how accurate you read RFC. You are example for me to follow :) As conclusion i agree, that brute force prevention isn't a part of HOTP and can be different in applications Anyway i need to solve my problem with brute force. Do you know open source projects, that realize it? Or maybe i need to start own and write simple anti-brute force wrapper library? |
@cyclopentan Glad it was useful! I have dug deep into many things 2FA related while working on my browser based 2FA manager called Two Factor Buddy (2FB) and content website All Things Auth where I write about authentication and authorization issues. This comment thread was a really useful motivator for me to re-read most of the HOTP RFC! Unfortunately, I do not know of any open source projects that offer the higher level of abstraction and implement HOTP/TOTP out of the box. I think it might be relatively specific to each application since there are choices about where/how to store the data, etc. Let us know if you find anything that meets your needs. Also, realize that TOTP has a constantly changing time window (counter C), so the brute force risks are lower than HOTP (because the counter C only increases when the user successfully logs in). For TOTP, I think it would be more than reasonable security and UX tradeoff to implement a max number of guesses T to be relatively low, such as 5. No user is going to manually put in the incorrect TOTP code more than 5 times in a 30 second window, so if there are more guesses than that, its software doing something wonky and you can just block it. Finally, I don't know what you're working on, but if the core value of your service is not providing authentication protocols, then I would definitely check out a third party that does this stuff all day every day instead of reinventing the wheel. For example, check out Duo or Authy. It is likely worth it so that you can focus on the core value of your product. Note: I am not associated with either company, but they are the big incumbents in the space and constantly come up in my research. |
@conorgil @cyclopentan From a library standpoint I'm definitely open for additional packages or just examples / samples of common patterns or platforms (thats why I structured it in a "packages > package" format. However, we need to be careful about adding implementations that are too specific as well (especially in core), as I am afraid that examples will end up being construed as "best practices" that need to be maintained constantly with moving standards of the industry. |
@conorgil I mean one-off authentication brute force, not secret key brute Math explanation: When you try random token, probability of successful auth is
Lets count probability of successful auth in case of Finally For 500 000 attemps probability of succesfull auth is about 40%, for 1 000 000 is 60% As you see it don't connected to window, only to tries count. So 5 tries per 30 second TOTP window can be broken with 40% probability in about 1 month Because |
@cyclopentan I do not follow. Are you worried about someone brute forcing a single OTP for a given counter If you haven't already, definitely check out Appendix A of the HOTP RFC "Appendix A - HOTP Algorithm Security: Detailed Analysis". It contains the mathematical proof that the authors use to backup claim that brute force is the best possible attack on HOTP. A.4.3. Brute force attacks are the best possible attacks.
Sorry I'm not following here. It might be easier for me if you can explain the specific brute force attack that you're trying to prevent without diving into the mathematical proof details. Thanks! |
@conorgil attack is easy: try random token 5 times per 30 second and after month you will pass auth with 40% probability |
Closing this issue for now. Feel free to continue / open the discussion thread if you have any more thoughts! :) |
12 days = 12 * 24 * 60 * 60 seconds = 1 036 800 > 1 000 000.
1 try / sec will break code in 12 days, but really in 6 days(there is some math magic, believe me :) )
If TOTP is one factor it's fatal
Lets increase it to 20 years (10 really). If we limit speed to 1 try / 600 sec it will cause problem to user.
So first 50 attempts time waits
0 min x 10 tries
0,5 min x 10 tries
1 min x 10 tries
2 min x 10 tries
5 min x 10 tries
and then 10 min.
Another way is to require double code enter after 50 tries and limit timeout to 30 seconds.
In this case user will wait only 1,5 mins but combinations count will be 1 000 000 000 000, thats more than anyone can brute force :)
The text was updated successfully, but these errors were encountered: