Skip to content

Commit

Permalink
Merge pull request #19 from xin9le/hotfix/exp-nbf-nested-payload
Browse files Browse the repository at this point in the history
Fix misjudgment of exp / nbf if payload contains nested object
  • Loading branch information
neuecc authored Sep 30, 2022
2 parents 7afa840 + d670f06 commit a42cd44
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 20 deletions.
16 changes: 4 additions & 12 deletions src/LitJWT/JwtDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,7 @@ public DecodeResult TryDecode<T>(ReadOnlySpan<byte> utf8token, PayloadParser<T>
var reader = new System.Text.Json.Utf8JsonReader(decodedPayload);
while (reader.Read())
{
if (reader.TokenType == System.Text.Json.JsonTokenType.EndObject) break;

if (reader.TokenType == JsonTokenType.PropertyName)
if (reader.CurrentDepth == 1 && reader.TokenType == JsonTokenType.PropertyName)
{
if (reader.ValueTextEquals(JwtConstantsUtf8.Expiration))
{
Expand Down Expand Up @@ -358,9 +356,7 @@ public DecodeResult TryDecode<T>(ReadOnlySpan<char> token, PayloadParser<T> payl
var reader = new System.Text.Json.Utf8JsonReader(decodedPayload);
while (reader.Read())
{
if (reader.TokenType == System.Text.Json.JsonTokenType.EndObject) break;

if (reader.TokenType == JsonTokenType.PropertyName)
if (reader.CurrentDepth == 1 && reader.TokenType == JsonTokenType.PropertyName)
{
if (reader.ValueTextEquals(JwtConstantsUtf8.Expiration))
{
Expand Down Expand Up @@ -514,9 +510,7 @@ DecodeResult TryDecodeCore<T>(ReadOnlySpan<byte> utf8token, InternalPayloadParse
var reader = new System.Text.Json.Utf8JsonReader(decodedPayload);
while (reader.Read())
{
if (reader.TokenType == System.Text.Json.JsonTokenType.EndObject) break;

if (reader.TokenType == JsonTokenType.PropertyName)
if (reader.CurrentDepth == 1 && reader.TokenType == JsonTokenType.PropertyName)
{
if (reader.ValueTextEquals(JwtConstantsUtf8.Expiration))
{
Expand Down Expand Up @@ -652,9 +646,7 @@ DecodeResult TryDecodeCore<T>(ReadOnlySpan<char> token, InternalPayloadParser<T>
var reader = new System.Text.Json.Utf8JsonReader(decodedPayload);
while (reader.Read())
{
if (reader.TokenType == System.Text.Json.JsonTokenType.EndObject) break;

if (reader.TokenType == JsonTokenType.PropertyName)
if (reader.CurrentDepth == 1 && reader.TokenType == JsonTokenType.PropertyName)
{
if (reader.ValueTextEquals(JwtConstantsUtf8.Expiration))
{
Expand Down
100 changes: 92 additions & 8 deletions tests/LitJWT.Tests/DecodeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ public class PayloadNbf
{
public string Foo { get; set; }
public int Bar { get; set; }
public Payload Nested { get; set; }
public long nbf { get; set; }
}
public class PayloadExp
{
public string Foo { get; set; }
public int Bar { get; set; }
public Payload Nested { get; set; }
public long exp { get; set; }
}
[Fact]
Expand Down Expand Up @@ -97,20 +99,40 @@ public void VerifyExp()
var decoder = new JwtDecoder(new LitJWT.Algorithms.HS256Algorithm(key));

{
var payload = new PayloadExp { Bar = 1, Foo = "foo", exp = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadExp { Bar = 1, Foo = "foo", Nested = nested, exp = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var result = encoder.Encode(payload, null, (x, writer) => writer.Write(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(x))));

var decodeResult = decoder.TryDecode(result, x => JsonConvert.DeserializeObject<Payload>(Encoding.UTF8.GetString(x)), out var decodedPayload);
decodeResult.Should().Be(DecodeResult.FailedVerifyExpire);
}

{
var payload = new PayloadExp { Bar = 1, Foo = "foo", exp = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadExp { Bar = 1, Foo = "foo", Nested = nested, exp = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var result = encoder.Encode(payload, null, (x, writer) => writer.Write(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(x))));

var decodeResult = decoder.TryDecode(result, x => JsonConvert.DeserializeObject<Payload>(Encoding.UTF8.GetString(x)), out var decodedPayload);
decodeResult.Should().Be(DecodeResult.Success);
}

{
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadExp { Bar = 1, Foo = "foo", Nested = nested, exp = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var jwt = encoder.Encode(payload, null);

var decodeResult = decoder.TryDecode(jwt, out PayloadExp decodedPayload);
decodeResult.Should().Be(DecodeResult.FailedVerifyExpire);
}

{
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadExp { Bar = 1, Foo = "foo", Nested = nested, exp = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var jwt = encoder.Encode(payload, null);

var decodeResult = decoder.TryDecode(jwt, out PayloadExp decodedPayload);
decodeResult.Should().Be(DecodeResult.Success);
}
}

[Fact]
Expand All @@ -121,7 +143,8 @@ public void VerifyNbf()
var decoder = new JwtDecoder(new LitJWT.Algorithms.HS256Algorithm(key));

{
var payload = new PayloadNbf { Bar = 1, Foo = "foo", nbf = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadNbf { Bar = 1, Foo = "foo", Nested = nested, nbf = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var result = encoder.Encode(payload, null, (x, writer) => writer.Write(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(x))));


Expand All @@ -130,14 +153,33 @@ public void VerifyNbf()
decodeResult.Should().Be(DecodeResult.FailedVerifyNotBefore);
}
{
var payload = new PayloadNbf { Bar = 1, Foo = "foo", nbf = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadNbf { Bar = 1, Foo = "foo", Nested = nested, nbf = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var result = encoder.Encode(payload, null, (x, writer) => writer.Write(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(x))));


var decodeResult = decoder.TryDecode(result, x => JsonConvert.DeserializeObject<Payload>(Encoding.UTF8.GetString(x)), out var decodedPayload);

decodeResult.Should().Be(DecodeResult.Success);
}

{
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadNbf { Bar = 1, Foo = "foo", Nested = nested, nbf = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var jwt = encoder.Encode(payload, null);

var decodeResult = decoder.TryDecode(jwt, out PayloadNbf decodedPayload);
decodeResult.Should().Be(DecodeResult.FailedVerifyNotBefore);
}

{
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadNbf { Bar = 1, Foo = "foo", Nested = nested, nbf = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var jwt = encoder.Encode(payload, null);

var decodeResult = decoder.TryDecode(jwt, out PayloadNbf decodedPayload);
decodeResult.Should().Be(DecodeResult.Success);
}
}


Expand Down Expand Up @@ -210,20 +252,40 @@ public void VerifyExpUtf8()
var decoder = new JwtDecoder(new LitJWT.Algorithms.HS256Algorithm(key));

{
var payload = new PayloadExp { Bar = 1, Foo = "foo", exp = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadExp { Bar = 1, Foo = "foo", Nested = nested, exp = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var result = encoder.EncodeAsUtf8Bytes(payload, null, (x, writer) => writer.Write(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(x))));

var decodeResult = decoder.TryDecode(result, x => JsonConvert.DeserializeObject<Payload>(Encoding.UTF8.GetString(x)), out var decodedPayload);
decodeResult.Should().Be(DecodeResult.FailedVerifyExpire);
}

{
var payload = new PayloadExp { Bar = 1, Foo = "foo", exp = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadExp { Bar = 1, Foo = "foo", Nested = nested, exp = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var result = encoder.EncodeAsUtf8Bytes(payload, null, (x, writer) => writer.Write(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(x))));

var decodeResult = decoder.TryDecode(result, x => JsonConvert.DeserializeObject<Payload>(Encoding.UTF8.GetString(x)), out var decodedPayload);
decodeResult.Should().Be(DecodeResult.Success);
}

{
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadExp { Bar = 1, Foo = "foo", Nested = nested, exp = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var jwt = encoder.EncodeAsUtf8Bytes(payload, null);

var decodeResult = decoder.TryDecode(jwt, out PayloadExp decodedPayload);
decodeResult.Should().Be(DecodeResult.FailedVerifyExpire);
}

{
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadExp { Bar = 1, Foo = "foo", Nested = nested, exp = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var jwt = encoder.EncodeAsUtf8Bytes(payload, null);

var decodeResult = decoder.TryDecode(jwt, out PayloadExp decodedPayload);
decodeResult.Should().Be(DecodeResult.Success);
}
}

[Fact]
Expand All @@ -234,7 +296,8 @@ public void VerifyNbfUtf8()
var decoder = new JwtDecoder(new LitJWT.Algorithms.HS256Algorithm(key));

{
var payload = new PayloadNbf { Bar = 1, Foo = "foo", nbf = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadNbf { Bar = 1, Foo = "foo", Nested = nested, nbf = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var result = encoder.EncodeAsUtf8Bytes(payload, null, (x, writer) => writer.Write(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(x))));


Expand All @@ -243,12 +306,33 @@ public void VerifyNbfUtf8()
decodeResult.Should().Be(DecodeResult.FailedVerifyNotBefore);
}
{
var payload = new PayloadNbf { Bar = 1, Foo = "foo", nbf = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadNbf { Bar = 1, Foo = "foo", Nested = nested, nbf = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var result = encoder.EncodeAsUtf8Bytes(payload, null, (x, writer) => writer.Write(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(x))));


var decodeResult = decoder.TryDecode(result, x => JsonConvert.DeserializeObject<Payload>(Encoding.UTF8.GetString(x)), out var decodedPayload);

decodeResult.Should().Be(DecodeResult.Success);
}
{
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadNbf { Bar = 1, Foo = "foo", Nested = nested, nbf = (DateTimeOffset.UtcNow + TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var jwt = encoder.EncodeAsUtf8Bytes(payload, null);


var decodeResult = decoder.TryDecode(jwt, out PayloadNbf decodedPayload);

decodeResult.Should().Be(DecodeResult.FailedVerifyNotBefore);
}
{
var nested = new Payload { Bar = 2, Foo = "foo2" };
var payload = new PayloadNbf { Bar = 1, Foo = "foo", Nested = nested, nbf = (DateTimeOffset.UtcNow - TimeSpan.FromSeconds(10)).ToUnixTimeSeconds() };
var jwt = encoder.EncodeAsUtf8Bytes(payload, null);


var decodeResult = decoder.TryDecode(jwt, out PayloadNbf decodedPayload);

decodeResult.Should().Be(DecodeResult.Success);
}
}
Expand Down

0 comments on commit a42cd44

Please sign in to comment.