diff --git a/src/jwt-model.ts b/src/jwt-model.ts index f4db0fc..1b67d9a 100644 --- a/src/jwt-model.ts +++ b/src/jwt-model.ts @@ -21,6 +21,7 @@ export type JwtHeader = JwtHeaderStandardFields & JsonObject; interface JwtPayloadStandardFields { exp?: number; // expires: https://tools.ietf.org/html/rfc7519#section-4.1.4 iss?: string; // issuer: https://tools.ietf.org/html/rfc7519#section-4.1.1 + sub?: string; // subject: https://tools.ietf.org/html/rfc7519#section-4.1.2 aud?: string | string[]; // audience: https://tools.ietf.org/html/rfc7519#section-4.1.3 nbf?: number; // not before: https://tools.ietf.org/html/rfc7519#section-4.1.5 iat?: number; // issued at: https://tools.ietf.org/html/rfc7519#section-4.1.6 diff --git a/src/jwt.ts b/src/jwt.ts index 9fbfb07..895a1ed 100644 --- a/src/jwt.ts +++ b/src/jwt.ts @@ -58,6 +58,9 @@ function assertJwtPayload( if (payload.iss !== undefined && typeof payload.iss !== "string") { throw new JwtParseError("JWT payload iss claim is not a string"); } + if (payload.sub !== undefined && typeof payload.sub !== "string") { + throw new JwtParseError("JWT payload sub claim is not a string"); + } if ( payload.aud !== undefined && typeof payload.aud !== "string" && diff --git a/tests/unit/jwt-rsa.test.ts b/tests/unit/jwt-rsa.test.ts index 96eb4dc..2c17f6c 100644 --- a/tests/unit/jwt-rsa.test.ts +++ b/tests/unit/jwt-rsa.test.ts @@ -430,6 +430,18 @@ describe("unit tests jwt verifier", () => { expect(statement).toThrow("JWT payload iss claim is not a string"); expect(statement).toThrow(JwtParseError); }); + test("JWT with sub that is not a string", () => { + const header = base64url('{"alg":"RS256"}'); + const payload = base64url('{"sub":12345}'); + const signedJwt = `${header}.${payload}.signature`; + const statement = () => + verifyJwtSync(signedJwt, keypair.jwk, { + audience: null, + issuer: null, + }); + expect(statement).toThrow("JWT payload sub claim is not a string"); + expect(statement).toThrow(JwtParseError); + }); test("JWT with aud that is not a string", () => { const header = base64url('{"alg":"RS256"}'); const payload = base64url('{"aud":12345}');