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

Update exp and nbf validation to use double parsing #89

Merged
merged 6 commits into from
Apr 20, 2017

Conversation

zemien
Copy link
Contributor

@zemien zemien commented Apr 20, 2017

Update exp and nbf validation to be based on strictly-parsed doubles for 2 reasons: Support dates beyond year 2038, and prevent treating nulls as 0.

… for 2 reasons: Support dates beyond year 2038, and prevent treating nulls as 0.
@zemien
Copy link
Contributor Author

zemien commented Apr 20, 2017

#89 fix

try
{
expInt = Convert.ToInt32(expObj);
expInt = double.Parse(expObj.ToString());
Copy link
Member

Choose a reason for hiding this comment

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

Double.ToString() has current culture issues. Please use Convert.ToDouble() instead

try
{
nbfInt = Convert.ToInt32(nbfObj);
nbfInt = double.Parse(nbfObj.ToString());
Copy link
Member

Choose a reason for hiding this comment

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

And here please

var serializer = new JsonNetSerializer();
JsonWebToken.JsonSerializer = serializer;

var post2038 = new DateTime(3000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Copy link
Member

Choose a reason for hiding this comment

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

Should we use 2038/1/1 + 1 second here? To justify variable's name

public void DecodeToObject_Should_Throw_Exception_Before_NotBefore_Becomes_Valid()
{
var nbf = (int)(DateTime.UtcNow.AddHours(1) - JwtValidator.UnixEpoch).TotalSeconds;
var post2038 = new DateTime(3000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Copy link
Member

Choose a reason for hiding this comment

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

And here

@zemien
Copy link
Contributor Author

zemien commented Apr 20, 2017

I've reverted back to using Convert and added a separate null check to ensure it doesn't get converted to 0.

}
catch
{
throw new SignatureVerificationException("Claim 'exp' must be an integer.");
throw new SignatureVerificationException(string.Format(claimMustBeDoubleFormat, "exp"));
Copy link
Member

Choose a reason for hiding this comment

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

Let's don't extract strings into const variables to keep the source code smaller and more readable

@@ -67,10 +67,20 @@ public void DecodeToObject_Should_Throw_Exception_On_Invalid_Expiration_Claim()
}

[Fact]
public void DecodeToObject_Should_Throw_Exception_On_Null_Expiration_Claim()
Copy link
Member

Choose a reason for hiding this comment

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

Sorry for confusing. Encode/Decode tests are for now-obsolete static API which we'll remove shortly. Can you please move new tests to JwtEncoder/Decoder tests?

@zemien
Copy link
Contributor Author

zemien commented Apr 20, 2017

Reverted the constant change. I knew it would be contentious so made it a separate commit ;)
Ported the tests to JwtDecoder

@abatishchev
Copy link
Member

Looks good to me. Thanks for this work!

Let's keep till EoD so @nbarbettini could give a quick look. And I'll merge.

Thanks again :)

@abatishchev abatishchev added this to the 2.0 milestone Apr 20, 2017
@abatishchev abatishchev self-assigned this Apr 20, 2017
@nbarbettini
Copy link
Contributor

Thanks for the Y2038 catch, @zemien! One question - why double and not long (Int64)?

@zemien
Copy link
Contributor Author

zemien commented Apr 20, 2017

Hmm good question. I suppose most approaches for calculating epoch in .Net uses the TotalSeconds property which is a double. Logically "seconds since epoch" do not appear to represent fractional seconds, but then again is there a reason to stop someone from specifying 0.5 (Jan 1, 1970 at 00:00:00.500)?

}
catch
{
throw new SignatureVerificationException("Claim 'exp' must be an integer.");
throw new SignatureVerificationException("Claim 'exp' must be a double.");
Copy link
Contributor

Choose a reason for hiding this comment

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

I think "Claim 'exp' must be a number." would remove some potential confusion from the error message.

int nbfInt;
if (nbfObj == null)
{
throw new SignatureVerificationException("Claim 'nbf' must be a double.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto

}
catch
{
throw new SignatureVerificationException("Claim 'nbf' must be an integer.");
throw new SignatureVerificationException("Claim 'nbf' must be a double.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto3

throw new SignatureVerificationException("Claim 'exp' must be a double.");
}

double expInt;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: This should be expValue or just exp.

@nbarbettini
Copy link
Contributor

is there a reason to stop someone from specifying 0.5

No reason, I think using double is fine. I forgot that TotalSeconds was a floating-point value.

Code looks good! 👍 Sent you a few minor comments.

@zemien
Copy link
Contributor Author

zemien commented Apr 20, 2017

Done, please review

Copy link
Contributor

@nbarbettini nbarbettini left a comment

Choose a reason for hiding this comment

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

LGTM

@abatishchev abatishchev merged commit 89f8260 into jwt-dotnet:master Apr 20, 2017
@zemien zemien deleted the double-date-parsing branch April 21, 2017 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants