Verification codes starting with 0 handled incorrectly
mpwaldhorst opened this issue · comments
Due to the usage of integers in the code comparison of a hash starting with a zero is handled incorrectly.
This causes the 0 at the start of the verification code to be truncated and therefore not used in the comparison.
To summarize we have the following situation
Expected verification code = 012345
Entered verification code = 12345
Result = valid verification code
Expected result = verification code is invalid
The RFC returns strings when generating the totp code.
Hi @mpwaldhorst, I guess you're not parsing integers correctly. In this implementation, codes are integers. Hence, there's no 0-padding. Zero-padding is a representation: if the zero-padded validation code is "000001", it's integer representation is 1.
Sorry maybe I wasn't completely clear in my explanation.
The 0-padded codes are handled correctly.
What I was trying to note is that the current implementation does not force the whole verification code to be the same if the expected code starts with a 0.
For example if the Google Authenticator app on iOS would generate a code with 012345 (which it does from time to time) and I forget the 0 and only enter 12345 in the two factor authentication, the implementation of this library will tell me that the code is correct even if the code I should have entered was 012345.
For correctness I would expect the library to also check the 0-padding to ensure that the entered code is truly the expected value.
Hi @mpwaldhorst, you can't really "forget" a 0: the library use integers, so when a human being reads a 0 padded number there must be a parsing stage from the user input to the integer output that is fed to the library. And since there is the representation is equivalent, the library is not lenient: it just expects you to parse correctly the 0-padded string to integer. If you want to check the size of the 0-pad string before parsing it is up to you.
Thank you for the quick responses.
I do agree that from a security standpoint the check without the 0 should not be an issue.
Checking the length of the input of the user can of course be done separately.
I just thought this might be something that you should be aware of as it could be seen as a little bit of a quirk. ;)
Keep up the good work!
Thanks for the feedback: it's always good. When I decided to use an integer representation I expected it not to be intuitive for some. But at the end I convinced myself it was just easier to deal with integers than with strings and implemented it like this.
Thanks!