Skip to content

Commit

Permalink
fix: added aud and azp validations for ID Tokens passed by clients
Browse files Browse the repository at this point in the history
specifically id_token_hints belonging to the auth request client
  • Loading branch information
panva committed Nov 25, 2018
1 parent e44ea4a commit 4df8160
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 12 deletions.
1 change: 1 addition & 0 deletions lib/actions/authorization/decode_request.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ module.exports = (provider, PARAM_LIST) => {
issuer: payload.iss ? client.clientId : undefined,
audience: payload.aud ? provider.issuer : undefined,
clockTolerance: conf('clockTolerance'),
ignoreAzp: true,
};
await JWT.verify(params.request, client.keystore, opts);
wasSignedOrEncrypted = true;
Expand Down
19 changes: 14 additions & 5 deletions lib/helpers/jwt.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,17 @@ const { stringify, parse } = JSON;
const format = 'compact';
const typ = 'JWT';

function verifyAudience({ aud }, expected) {
const target = Array.isArray(aud) ? aud : [aud];
const match = target.some(actual => actual === expected);
assert(match, `jwt audience missing ${expected}`);
function verifyAudience({ aud, azp }, expected, checkAzp) {
if (Array.isArray(aud)) {
const match = aud.some(actual => actual === expected);
assert(match, `jwt audience missing ${expected}`);
if (checkAzp) {
assert(azp, 'jwt missing azp claim');
assert.strictEqual(azp, expected, 'invalid jwt azp');
}
} else {
assert.strictEqual(aud, expected, `jwt audience missing ${expected}`);
}
}

class JWT {
Expand Down Expand Up @@ -57,7 +64,8 @@ class JWT {
}

static assertPayload(payload, {
clockTolerance = 0, audience, ignoreExpiration, ignoreIssued, ignoreNotBefore, issuer, jti,
clockTolerance = 0, audience, ignoreExpiration,
ignoreAzp, ignoreIssued, ignoreNotBefore, issuer, jti,
} = {}) {
const timestamp = epochTime();

Expand Down Expand Up @@ -86,6 +94,7 @@ class JWT {
verifyAudience(
payload,
audience,
!ignoreAzp,
);
}

Expand Down
11 changes: 7 additions & 4 deletions lib/models/id_token.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ module.exports = function getIdToken(provider) {
const alg = client.idTokenSignedResponseAlg;
const opts = {
ignoreExpiration: true,
audience: client.clientId,
issuer: provider.issuer,
clockTolerance: instance(provider).configuration('clockTolerance'),
};
Expand All @@ -161,11 +162,13 @@ module.exports = function getIdToken(provider) {
keyOrStore = client.keystore;
}

if (keyOrStore !== undefined) return JWT.verify(jwt, keyOrStore, opts);
if (keyOrStore !== undefined) {
return JWT.verify(jwt, keyOrStore, opts);
}

const decode = JWT.decode(jwt);
JWT.assertPayload(decode.payload, opts);
return decode;
const decoded = JWT.decode(jwt);
JWT.assertPayload(decoded.payload, opts);
return decoded;
}
};
};
1 change: 1 addition & 0 deletions lib/shared/token_jwt_auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ module.exports = function getTokenJwtAuth(provider, endpoint) {
audience: endpointUri,
issuer: ctx.oidc.client.clientId,
clockTolerance: instance(provider).configuration('clockTolerance'),
ignoreAzp: true,
});
} catch (err) {
throw new InvalidClientAuth(err.message);
Expand Down
5 changes: 3 additions & 2 deletions test/jwt/jsonwebtoken.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,10 @@ describe('JSON Web Token (JWT) RFC7519 implementation', () => {
const key = keystore.get({ kty: 'oct' });
return JWT.sign({ data: true }, key, 'HS256', {
audience: ['client', 'momma'],
authorizedParty: 'client',
})
.then(jwt => JWT.verify(jwt, key, {
audience: 'momma',
audience: 'client',
}));
});

Expand All @@ -272,7 +273,7 @@ describe('JSON Web Token (JWT) RFC7519 implementation', () => {
audience: 'client',
})
.then(jwt => JWT.verify(jwt, key, {
audience: ['pappa'],
audience: 'pappa',
}))
.then((valid) => {
expect(valid).not.to.be.ok;
Expand Down
2 changes: 1 addition & 1 deletion test/storage/jwt.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if (FORMAT === 'jwt') {
const redirectUri = 'https://rp.example.com/cb';
const codeChallenge = 'codeChallenge';
const codeChallengeMethod = 'codeChallengeMethod';
const aud = [clientId, 'foo'];
const aud = ['foo', 'bar'];
const gty = 'foo';
const error = 'access_denied';
const errorDescription = 'resource owner denied access';
Expand Down

0 comments on commit 4df8160

Please sign in to comment.