Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@jamesob
Copy link

@jamesob jamesob commented Mar 3, 2014

Hi, thanks for the library. While using pyotp, I noticed that if you pass in an OTP to be verified as a string, the equality check will fail (despite the docstring advertising strings as being acceptable). I've attached a patch that fixes this.

Copy link

Choose a reason for hiding this comment

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

@param [String/Integer] otp the OTP to check against

Why do you assume the otp is an int while the doc clearly says otherwise?

Copy link
Member

Choose a reason for hiding this comment

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

I guess the solution that preserves the original semantics is to return False instead of raising ValueError.

Copy link
Author

Choose a reason for hiding this comment

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

@pypingou I don't think you realize that as the code is now, passing in a string for otp will cause this function to return False regardless of the otp value.

Copy link
Member

Choose a reason for hiding this comment

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

@jamesob your change will break code that passes in values without casting them. It will start raising instead of returning False. Given the current API, it is safer to return False instead of raising.

Moreover, it's not a given that OTPs are numeric. See https://www.ietf.org/rfc/rfc4226.txt section E.2.

Copy link
Author

Choose a reason for hiding this comment

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

@kislyuk but it is a given that OTPs are numeric in this library. Check out generate_otp. Re: breaking changes: see my latest comment in the main thread.

Copy link
Member

Choose a reason for hiding this comment

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

It is a given in this class. By enforcing constraints here, you force
implementations that inherit from this class into also reimplementing this
method.
On Mar 5, 2014 8:11 AM, "jamesob" [email protected] wrote:

In src/pyotp/hotp.py:

 def verify(self, otp, counter):
     """
     Verifies the OTP passed in against the current time OTP
     @param [String/Integer] otp the OTP to check against
     @param [Integer] counter the counter of the OTP
     """
  •    try:
    
  •        otp = int(otp)
    

@kislyuk https://github.com/kislyuk but it is a given that OTPs are
numeric in this library. Check out generate_otp. Re: breaking changes:
see my latest comment in the main thread.


Reply to this email directly or view it on GitHubhttps://github.com//pull/1/files#r10305408
.

Copy link
Author

Choose a reason for hiding this comment

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

s/this class/all classes provided by this package

A return type of int is also implicitly assumed in HOTP (see here)

If you can show me one instance of a generate_otp override with a non-numeric return type in the wild, I'll eat my shoes.

@pypingou
Copy link

pypingou commented Mar 4, 2014

Seeing the commit message, I think a better fix would actually be to convert everything to a string before doing the comparison str(otp) == str(self.at(counter))

@nathforge
Copy link

Oops! Thanks for finding that!

String support would be a useful feature. I'd prefer to not throw new exceptions, and cast both operands to unicode.

Might be able to work on it this weekend - if anybody wants to do it before then, some non-integer otp tests would be appreciated.

@jamesob
Copy link
Author

jamesob commented Mar 4, 2014

@nathforge some non-integer tests are already attached.
out of curiosity, what's the benefit of casting both to unicode over casting one to int and preserving the return type of TOTP.at?

@kislyuk
Copy link
Member

kislyuk commented Mar 4, 2014

@jamesob see my other comment. Also, you don't have to change the return type of TOTP.at :)

@nathforge
Copy link

@jamesob I reckon if we're supporting strings, we should expect unsanitised user input. I don't think there's value in throwing an exception on something like "!£$%^", rather than saying "no, your password's incorrect".

@jamesob
Copy link
Author

jamesob commented Mar 5, 2014

fellas, unless I am seriously mistaken about the return type of the expression code % 10 ** self.digits, generate_otp will always return an int, meaning so will at, meaning that any string passed into verify will return False whether or not it semantically matches the value returned by at.

It sounds like the least controversial solution here is to simply remove the advertisement of string support from verify's docstring. This isn't very pythonic though, because a string passed in will implicitly fail, returning False, instead of failing explicitly and alerting the user that their usage is incorrect.

I recommend you slate this for a compatibility-breaking point release.

@pypingou
Copy link

pypingou commented Mar 5, 2014

Don't you by using unicode(otp) == unicode(self.at(counter)) solve the addressed problem and keep the possibility that the otp might become non-numeric w/o breaking backward compatibility?

@jamesob
Copy link
Author

jamesob commented Mar 5, 2014

@pypingou yeah, that's fine with me. will submit a patch to that effect.

@jamesob
Copy link
Author

jamesob commented Mar 5, 2014

added commit and renamed PR

@jamesob
Copy link
Author

jamesob commented Mar 5, 2014

but do realize that this will change behavior of the library -- verify calls that before failed for semantic matches (but differing in type) will now pass. Note that I'm in support of this, but there seems to be a lot of concern re: backwards compat.

@nathforge
Copy link

Doesn't sound like a showstopper, but I'll bump version to 1.4 anyhow. Thanks for your help, all!

nathforge added a commit that referenced this pull request Mar 5, 2014
Normalize `verify` otp param before comparison
@nathforge nathforge merged commit 656a0db into pyauth:master Mar 5, 2014
@nathforge
Copy link

Uploaded v1.4 to PyPI.

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.

4 participants