From 54657795d41047bb7e502c877d3b385b1673017e Mon Sep 17 00:00:00 2001 From: Dimitris Soldatos Date: Thu, 12 May 2022 17:56:22 +0300 Subject: [PATCH] fix(security): regex validation issue (#149) --- .../src/admin/routes/CreateSecurityClient.route.ts | 13 +++++++++++-- packages/security/src/utils/security.ts | 6 ++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/security/src/admin/routes/CreateSecurityClient.route.ts b/packages/security/src/admin/routes/CreateSecurityClient.route.ts index 01cfcff98..e5ba93e34 100644 --- a/packages/security/src/admin/routes/CreateSecurityClient.route.ts +++ b/packages/security/src/admin/routes/CreateSecurityClient.route.ts @@ -36,8 +36,17 @@ export function getCreateSecurityClientRoute() { let clientId = randomBytes(15).toString('hex'); let clientSecret = randomBytes(64).toString('hex'); let hash = await bcrypt.hash(clientSecret, 10); - if (platform === PlatformTypesEnum.WEB && !domain) { - throw new ConduitError('INVALID_ARGUMENTS', 400, 'Platform WEB requires domain name'); + if (platform === PlatformTypesEnum.WEB) { + if (!domain || domain === '') + throw new ConduitError('INVALID_ARGUMENTS', 400, 'Platform WEB requires domain name'); + if (domain.replace(/[^*]/g, '').length > 1) { + throw new ConduitError('INVALID_ARGUMENTS', 400, `Domain must not contain more than one '*' character` ); + } + if (domain.includes('*')) { + const [_, splittedDomain] = domain.split('*.'); + const domainPattern = new RegExp('^(?!-)[A-Za-z0-9-]+([\\-\\.]{1}[a-z0-9]+)*\\.[A-Za-z]{2,6}$') + if (!domainPattern.test(splittedDomain)) throw new ConduitError('INVALID_ARGUMENTS', 400, 'Invalid domain argument'); + } } let client = await Client.getInstance().create({ clientId, diff --git a/packages/security/src/utils/security.ts b/packages/security/src/utils/security.ts index efac76b4f..5b7ab7c0d 100644 --- a/packages/security/src/utils/security.ts +++ b/packages/security/src/utils/security.ts @@ -13,16 +13,18 @@ export async function validateClient( ) { let match; if (client.platform === PlatformTypesEnum.WEB && client.domain) { + if (client.domain === '*') return true; const isRegex = client.domain.includes('*'); const sendDomain = req.get('origin') ?? req.hostname; if (isRegex) { - match = (client.domain as any).test(sendDomain); // check if the regex matches with the hostname + const [_, regex] = client.domain.split('*.'); + match = sendDomain.endsWith(regex); // check if the regex matches with the hostname } else { match = (client.domain === sendDomain); } return match; } - let clientsecret = req.headers.clientsecret + let clientsecret = req.headers.clientsecret; if (fromRedis) { return clientsecret === client.clientSecret; }