Skip to content

Commit

Permalink
fix: block static client registration read action (edgiest of cases)
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Jul 8, 2019
1 parent 74a0f04 commit 18db430
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 9 deletions.
16 changes: 9 additions & 7 deletions lib/actions/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ module.exports = {
...validateRegistrationAccessToken,

async function clientReadResponse(ctx, next) {
if (ctx.oidc.client.noManage) {
throw new InvalidRequest('client does not have permission to read its record', 403);
}

ctx.body = ctx.oidc.client.metadata();

Object.assign(ctx.body, {
Expand Down Expand Up @@ -181,24 +185,22 @@ module.exports = {
async function equalChecks(ctx, next) {
ctx.assert(ctx.oidc.body.client_id === ctx.oidc.client.clientId, new InvalidRequest('provided client_id does not match the authenticated client\'s one'));

if (typeof ctx.oidc.body.client_secret === 'string') {
if ('client_secret' in ctx.oidc.body) {
const clientSecretValid = constantEquals(
ctx.oidc.body.client_secret,
ctx.oidc.client.clientSecret,
typeof ctx.oidc.body.client_secret === 'string' ? ctx.oidc.body.client_secret : '',
ctx.oidc.client.clientSecret || '',
1000,
);

ctx.assert(clientSecretValid, new InvalidRequest('provided client_secret does not match the authenticated client\'s one'));
} else if ('client_secret' in ctx.oidc.body) {
throw new InvalidRequest('provided client_secret does not match the authenticated client\'s one');
}

await next();
},

async function clientUpdateResponse(ctx, next) {
if (ctx.oidc.client.noManage) {
throw new InvalidRequest('this client is not allowed to update its records', 403);
throw new InvalidRequest('client does not have permission to update its record', 403);
}

const properties = chain({}).defaults({
Expand Down Expand Up @@ -275,7 +277,7 @@ module.exports = {

async function clientRemoveResponse(ctx, next) {
if (ctx.oidc.client.noManage) {
throw new InvalidRequest('this client is not allowed to delete itself', 403);
throw new InvalidRequest('client does not have permission to delete its record', 403);
}

const { oidc: { provider } } = ctx;
Expand Down
5 changes: 5 additions & 0 deletions test/dynamic_registration/dynamic_registration.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ config.features = { registration: { enabled: true } };

module.exports = {
config,
client: {
client_id: 'client',
client_secret: 'secret',
redirect_uris: ['https://client.example.com/cb'],
},
};
8 changes: 8 additions & 0 deletions test/dynamic_registration/dynamic_registration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,5 +406,13 @@ describe('registration features', () => {
expect(spy.firstCall.args[0].clientId).to.equal(this.clientId);
});
});

it('cannot read non-dynamic clients', async function () {
const rat = new (this.provider.RegistrationAccessToken)({ clientId: 'client' });
const bearer = await rat.save();
return this.agent.get('/reg/client')
.auth(bearer, { type: 'bearer' })
.expect(this.failWith(403, 'invalid_request', 'client does not have permission to read its record'));
});
});
});
4 changes: 2 additions & 2 deletions test/registration_management/registration_management.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ describe('OAuth 2.0 Dynamic Client Registration Management Protocol', () => {
.send(updateProperties(client.metadata(), {
redirect_uris: ['https://client.example.com/foobar/cb'],
}))
.expect(this.failWith(403, 'invalid_request', 'this client is not allowed to update its records'));
.expect(this.failWith(403, 'invalid_request', 'client does not have permission to update its record'));
});

describe('rotateRegistrationAccessToken', () => {
Expand Down Expand Up @@ -322,7 +322,7 @@ describe('OAuth 2.0 Dynamic Client Registration Management Protocol', () => {
const bearer = await rat.save();
return this.agent.del('/reg/client')
.auth(bearer, { type: 'bearer' })
.expect(this.failWith(403, 'invalid_request', 'this client is not allowed to delete itself'));
.expect(this.failWith(403, 'invalid_request', 'client does not have permission to delete its record'));
});
});
});

0 comments on commit 18db430

Please sign in to comment.