match url whitelist to domain (#5694)

* match url whitelist to domain

* Improve url-domain check

* Update lockfile

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
Adam Sparks
2021-06-09 14:12:34 -05:00
committed by GitHub
parent 7ecbe49bb6
commit c1b30a6d8c
3 changed files with 33 additions and 7 deletions

View File

@@ -14,6 +14,7 @@ import {
import { RecordNotUniqueException } from '../exceptions/database/record-not-unique';
import logger from '../logger';
import { AbstractServiceOptions, Accountability, Item, PrimaryKey, Query, SchemaOverview } from '../types';
import isUrlAllowed from '../utils/is-url-allowed';
import { toArray } from '../utils/to-array';
import { AuthenticationService } from './authentication';
import { ItemsService, MutationOptions } from './items';
@@ -226,9 +227,7 @@ export class UsersService extends ItemsService {
async inviteUser(email: string | string[], role: string, url: string | null, subject?: string | null): Promise<void> {
const emails = toArray(email);
const urlWhitelist = toArray(env.USER_INVITE_URL_ALLOW_LIST);
if (url && urlWhitelist.includes(url) === false) {
if (url && isUrlAllowed(url, env.USER_INVITE_URL_ALLOW_LIST) === false) {
throw new InvalidPayloadException(`Url "${url}" can't be used to invite users.`);
}
@@ -305,9 +304,7 @@ export class UsersService extends ItemsService {
const payload = { email, scope: 'password-reset' };
const token = jwt.sign(payload, env.SECRET as string, { expiresIn: '1d' });
const urlWhitelist = toArray(env.PASSWORD_RESET_URL_ALLOW_LIST);
if (url && urlWhitelist.includes(url) === false) {
if (url && isUrlAllowed(url, env.PASSWORD_RESET_URL_ALLOW_LIST) === false) {
throw new InvalidPayloadException(`Url "${url}" can't be used to reset passwords.`);
}

View File

@@ -0,0 +1,29 @@
import { toArray } from './to-array';
import logger from '../logger';
/**
* Check if url matches allow list either exactly or by domain+path
*/
export default function isUrlAllowed(url: string, allowList: string | string[]): boolean {
console.log(url, allowList);
const urlAllowList = toArray(allowList);
if (urlAllowList.includes(url)) return true;
const parsedWhitelist = urlAllowList.map((allowedURL) => {
try {
const { hostname, pathname } = new URL(allowedURL);
return hostname + pathname;
} catch {
logger.warn(`Invalid URL used "${url}"`);
}
});
try {
const { hostname, pathname } = new URL(url);
return parsedWhitelist.includes(hostname + pathname);
} catch {
return false;
}
}

2
package-lock.json generated
View File

@@ -72848,7 +72848,7 @@
"keyv": "^4.0.3",
"keyv-memcache": "^1.2.5",
"knex": "^0.95.6",
"knex-schema-inspector": "^1.5.6",
"knex-schema-inspector": "^1.5.7",
"liquidjs": "^9.25.0",
"lodash": "^4.17.21",
"macos-release": "^2.4.1",