Skip to content
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

Check digest function to prevent error on OTP Generation #170

Merged
merged 2 commits into from
Sep 3, 2024

Conversation

FaizRahiemy
Copy link

@FaizRahiemy FaizRahiemy commented Aug 31, 2024

Summary

This pull request introduces a validation check in the init and generate_otp functions to prevent errors caused by incompatible digest functions and inadequate digest sizes. The changes aim to improve the stability and reliability of OTP generation. While the RFC4226 states that the base function is sha1, the existing code will allow user to use other hash functions such as MD5 and SHAKE-128 due to their availability in the hashlib.

Changes Made

Digest Function Validation

Added checks to disallow the use of hashlib.md5 and hashlib.shake_128 as digest functions in the __init__ function of otp.py, hotp.py, and totp.py. These functions are not suitable for OTP generation due to their shorter hash sizes.

Digest Size Check

Implemented a check to ensure that the digest size is not lower than 18 bytes. This prevents an IndexError that could occur when the last hash byte is 0xF, causing the generate_otp function to set the offset to 15. The subsequent operation would attempt to access hmac_hash[offset + 1] and so on, leading to an out-of-bounds error for md5 and shake128 due to their shorter digest lengths.

Impact

  • Prevents potential errors and crashes during OTP generation by ensuring only suitable digest functions and sizes are used.
  • Improves overall code robustness by validating inputs before proceeding with OTP generation.

Testing

  • Tested that hashlib.md5 and hashlib.shake128 are correctly rejected as digest functions on __init__.
  • Tested the digest size check to ensure that digest lengths below 18 bytes trigger the appropriate error handling on generate_otp.
  • Added DigestFunctionTest unit test as a negative test case where it will trigger an error if the selected digest function is md5 or shake_128.

Comment on lines +32 to +36
elif digest in [
hashlib.md5,
hashlib.shake_128
]:
raise ValueError("selected digest function must generate digest size greater than or equals to 18 bytes")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I, for some reason (like auditing instrumentation), wrap md5 in a custom call, this won't catch it. Also, the list of overspecific; there might be more of such algorithms (in the future?), and we don't want to miss those.

It will thus be best to check the .digest_size attribute, as done in otp.py:generate_otp().

Comment on lines +35 to +39
elif digest in [
hashlib.md5,
hashlib.shake_128
]:
raise ValueError("selected digest function must generate digest size greater than or equals to 18 bytes")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can go away if the check is one in otp.py:generate_otp(): It is not necessary, and there should only be one place where the relevant check is done.

@kislyuk kislyuk merged commit 763be88 into pyauth:develop Sep 3, 2024
2 of 7 checks passed
@kislyuk
Copy link
Member

kislyuk commented Sep 3, 2024

Thanks for your contribution. There are a few issues that I will fix, but the idea is solid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants