#1 Re: mORMot 1 » JWT Decode Bug » 2022-03-27 17:35:57

It looks like commenting out the following line in SynCrypto.pas fixes this problem, although I don't know what other side-effects this might cause.

@ab Is this a valid solution? It seems to work when passing the resulting JSON to TDocVariantData.InitJSON() and then iterating through the fields.

procedure TJWTAbstract.Parse()
[...]
  if cap>0 then
  repeat
    N := GetJSONPropName(P);
    if N=nil then
      exit;
    V := GetJSONFieldOrObjectOrArray(P,@wasstring,@EndOfObject,true);
//    if V=nil then <<===============
//      exit;       <<===============
    len := StrLen(N);
    if len=3 then begin
      c := PInteger(N)^;
      for claim := low(claim) to high(claim) do
        if PInteger(JWT_CLAIMS_TEXT[claim])^=c then begin
          if V^=#0 then

#2 mORMot 1 » JWT Decode Bug » 2022-03-26 23:23:09

dougb
Replies: 2

If I decode a JWT that has a NULL field, then the verification fails and the decoding of the JSON payload stops at the field prior to the null value.

I'm sure I'm missing some expected behavior when it comes to null values, but couldn't find a solution after reading the documentation.

I first encountered this problem when trying to decode a JWT from a third party, where one of the fields was set to null.

Here's a console application that reproduces this error.

Program TestJwt;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, SynCrypto, SynCommons;

var
  claims: TDocVariantData;
  j: TJWTHS256;
  claimArray: TTVarRecDynArray;
  token: RawUTF8;
  jwtContent: TJWTContent;
begin
  try
    claims.Init([], dvArray);
    claims.AddItem('Field1'); claims.AddItem('value-1');
    claims.AddItem('Field2'); claims.AddItem('value-2');
    claims.AddItem('Field3'); claims.AddItem(Null);
    claims.AddItem('Field4'); claims.AddItem('value-4');
    claims.AddItem('Field5'); claims.AddItem('value-5');

    j := TJWTHS256.Create('secret', 0, [], []);
    try
      Writeln('TOKEN');
      Writeln('-----');
      claims.ToArrayOfConst(claimArray);
      token := j.Compute(claimArray);
      Writeln(token);

      Writeln;
      Writeln('DECODED TOKEN');
      Writeln('-------------');
      j.Verify(token, jwtContent);
      Writeln(jwtContent.data.ToJSON);

      if (jwtContent.result <> jwtValid) then
        Writeln('**INVALID** TOKEN')
      else
        Writeln('TOKEN IS VALID');

    finally
      j.Free;
    end;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Board footer

Powered by FluxBB