fix: harden username blocklist (#39281)
* fix: harden username blocklist Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
committed by
GitHub
parent
2cfee3ae96
commit
b58704a5ce
@ -13,6 +13,7 @@ import debugFactory from 'debug';
|
|||||||
import { isEmail } from 'validator';
|
import { isEmail } from 'validator';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import generate from 'nanoid/generate';
|
import generate from 'nanoid/generate';
|
||||||
|
import badwordFilter from 'bad-words';
|
||||||
|
|
||||||
import { apiLocation } from '../../../config/env';
|
import { apiLocation } from '../../../config/env';
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ import {
|
|||||||
renderSignInEmail
|
renderSignInEmail
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
import { blacklistedUsernames } from '../../server/utils/constants.js';
|
import { blocklistedUsernames } from '../../server/utils/constants.js';
|
||||||
import { wrapHandledError } from '../../server/utils/create-handled-error.js';
|
import { wrapHandledError } from '../../server/utils/create-handled-error.js';
|
||||||
import { saveUser, observeMethod } from '../../server/utils/rx.js';
|
import { saveUser, observeMethod } from '../../server/utils/rx.js';
|
||||||
import { getEmailSender } from '../../server/utils/url-utils';
|
import { getEmailSender } from '../../server/utils/url-utils';
|
||||||
@ -160,10 +161,10 @@ export default function(User) {
|
|||||||
// increase user accessToken ttl to 900 days
|
// increase user accessToken ttl to 900 days
|
||||||
User.settings.ttl = 900 * 24 * 60 * 60 * 1000;
|
User.settings.ttl = 900 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
// username should not be in blacklist
|
// username should not be in blocklist
|
||||||
User.validatesExclusionOf('username', {
|
User.validatesExclusionOf('username', {
|
||||||
in: blacklistedUsernames,
|
in: blocklistedUsernames,
|
||||||
message: 'is taken'
|
message: 'is not available'
|
||||||
});
|
});
|
||||||
|
|
||||||
// username should be unique
|
// username should be unique
|
||||||
@ -347,10 +348,14 @@ export default function(User) {
|
|||||||
if (!username && (!email || !isEmail(email))) {
|
if (!username && (!email || !isEmail(email))) {
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
log('checking existence');
|
log('check if username is available');
|
||||||
|
// check to see if username is on blocklist
|
||||||
// check to see if username is on blacklist
|
const usernameFilter = new badwordFilter();
|
||||||
if (username && blacklistedUsernames.indexOf(username) !== -1) {
|
if (
|
||||||
|
username &&
|
||||||
|
(blocklistedUsernames.includes(username) ||
|
||||||
|
usernameFilter.isProfane(username))
|
||||||
|
) {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
api-server/package-lock.json
generated
13
api-server/package-lock.json
generated
@ -2722,6 +2722,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bad-words": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bad-words/-/bad-words-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-To+nGz+U8SpEQieZ2kSadY/1hVO88UXAslCJuTgLjDOuGrs/tNW2BYwl0fctxcRLooe0nzYN1pGzgvRIrd0BeA==",
|
||||||
|
"requires": {
|
||||||
|
"badwords-list": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"badwords-list": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/badwords-list/-/badwords-list-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-XphW2/E0gqKVw7CzBK+51M/FxXk="
|
||||||
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
"accepts": "^1.3.7",
|
"accepts": "^1.3.7",
|
||||||
"auth0-js": "^9.13.2",
|
"auth0-js": "^9.13.2",
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
|
"bad-words": "^3.0.3",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"chai": "~3.4.1",
|
"chai": "~3.4.1",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
|
@ -4,7 +4,7 @@ for (let i = 0; i < 26; i++) {
|
|||||||
alphabet = alphabet.concat(String.fromCharCode(97 + i));
|
alphabet = alphabet.concat(String.fromCharCode(97 + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const blacklistedUsernames = [
|
let blocklist = [
|
||||||
...alphabet.split(''),
|
...alphabet.split(''),
|
||||||
'about',
|
'about',
|
||||||
'academic-honesty',
|
'academic-honesty',
|
||||||
@ -59,6 +59,7 @@ export const blacklistedUsernames = [
|
|||||||
'pmi-acp-agile-project-managers',
|
'pmi-acp-agile-project-managers',
|
||||||
'privacy-policy',
|
'privacy-policy',
|
||||||
'privacy',
|
'privacy',
|
||||||
|
'profile',
|
||||||
'project-completed',
|
'project-completed',
|
||||||
'reset',
|
'reset',
|
||||||
'services',
|
'services',
|
||||||
@ -83,5 +84,535 @@ export const blacklistedUsernames = [
|
|||||||
'update-my-theme',
|
'update-my-theme',
|
||||||
'update-my-username',
|
'update-my-username',
|
||||||
'user',
|
'user',
|
||||||
'wiki'
|
'username',
|
||||||
|
'wiki',
|
||||||
|
|
||||||
|
// some more names from https://github.com/marteinn/The-Big-Username-Blacklist-JS/blob/master/src/list.js
|
||||||
|
'.htaccess',
|
||||||
|
'.htpasswd',
|
||||||
|
'.well-known',
|
||||||
|
'400',
|
||||||
|
'401',
|
||||||
|
'403',
|
||||||
|
'404',
|
||||||
|
'405',
|
||||||
|
'406',
|
||||||
|
'407',
|
||||||
|
'408',
|
||||||
|
'409',
|
||||||
|
'410',
|
||||||
|
'411',
|
||||||
|
'412',
|
||||||
|
'413',
|
||||||
|
'414',
|
||||||
|
'415',
|
||||||
|
'416',
|
||||||
|
'417',
|
||||||
|
'421',
|
||||||
|
'422',
|
||||||
|
'423',
|
||||||
|
'424',
|
||||||
|
'426',
|
||||||
|
'428',
|
||||||
|
'429',
|
||||||
|
'431',
|
||||||
|
'500',
|
||||||
|
'501',
|
||||||
|
'502',
|
||||||
|
'503',
|
||||||
|
'504',
|
||||||
|
'505',
|
||||||
|
'506',
|
||||||
|
'507',
|
||||||
|
'508',
|
||||||
|
'509',
|
||||||
|
'510',
|
||||||
|
'511',
|
||||||
|
'about',
|
||||||
|
'about-us',
|
||||||
|
'abuse',
|
||||||
|
'access',
|
||||||
|
'account',
|
||||||
|
'accounts',
|
||||||
|
'ad',
|
||||||
|
'add',
|
||||||
|
'admin',
|
||||||
|
'administration',
|
||||||
|
'administrator',
|
||||||
|
'ads',
|
||||||
|
'advertise',
|
||||||
|
'advertising',
|
||||||
|
'aes128-ctr',
|
||||||
|
'aes128-gcm',
|
||||||
|
'aes192-ctr',
|
||||||
|
'aes256-ctr',
|
||||||
|
'aes256-gcm',
|
||||||
|
'affiliate',
|
||||||
|
'affiliates',
|
||||||
|
'ajax',
|
||||||
|
'alert',
|
||||||
|
'alerts',
|
||||||
|
'alpha',
|
||||||
|
'amp',
|
||||||
|
'analytics',
|
||||||
|
'api',
|
||||||
|
'app',
|
||||||
|
'apps',
|
||||||
|
'asc',
|
||||||
|
'assets',
|
||||||
|
'atom',
|
||||||
|
'auth',
|
||||||
|
'authentication',
|
||||||
|
'authorize',
|
||||||
|
'autoconfig',
|
||||||
|
'autodiscover',
|
||||||
|
'avatar',
|
||||||
|
'backup',
|
||||||
|
'banner',
|
||||||
|
'banners',
|
||||||
|
'beta',
|
||||||
|
'billing',
|
||||||
|
'billings',
|
||||||
|
'blog',
|
||||||
|
'blogs',
|
||||||
|
'board',
|
||||||
|
'bookmark',
|
||||||
|
'bookmarks',
|
||||||
|
'broadcasthost',
|
||||||
|
'business',
|
||||||
|
'buy',
|
||||||
|
'cache',
|
||||||
|
'calendar',
|
||||||
|
'campaign',
|
||||||
|
'captcha',
|
||||||
|
'careers',
|
||||||
|
'cart',
|
||||||
|
'cas',
|
||||||
|
'categories',
|
||||||
|
'category',
|
||||||
|
'cdn',
|
||||||
|
'cgi',
|
||||||
|
'cgi-bin',
|
||||||
|
'chacha20-poly1305',
|
||||||
|
'change',
|
||||||
|
'channel',
|
||||||
|
'channels',
|
||||||
|
'chart',
|
||||||
|
'chat',
|
||||||
|
'checkout',
|
||||||
|
'clear',
|
||||||
|
'client',
|
||||||
|
'close',
|
||||||
|
'cms',
|
||||||
|
'com',
|
||||||
|
'comment',
|
||||||
|
'comments',
|
||||||
|
'community',
|
||||||
|
'compare',
|
||||||
|
'compose',
|
||||||
|
'config',
|
||||||
|
'connect',
|
||||||
|
'contact',
|
||||||
|
'contest',
|
||||||
|
'cookies',
|
||||||
|
'copy',
|
||||||
|
'copyright',
|
||||||
|
'count',
|
||||||
|
'create',
|
||||||
|
'crossdomain.xml',
|
||||||
|
'css',
|
||||||
|
'curve25519-sha256',
|
||||||
|
'customer',
|
||||||
|
'customers',
|
||||||
|
'customize',
|
||||||
|
'dashboard',
|
||||||
|
'db',
|
||||||
|
'deals',
|
||||||
|
'debug',
|
||||||
|
'delete',
|
||||||
|
'desc',
|
||||||
|
'destroy',
|
||||||
|
'dev',
|
||||||
|
'developer',
|
||||||
|
'developers',
|
||||||
|
'diffie-hellman-group-exchange-sha256',
|
||||||
|
'diffie-hellman-group14-sha1',
|
||||||
|
'disconnect',
|
||||||
|
'discuss',
|
||||||
|
'dns',
|
||||||
|
'dns0',
|
||||||
|
'dns1',
|
||||||
|
'dns2',
|
||||||
|
'dns3',
|
||||||
|
'dns4',
|
||||||
|
'docs',
|
||||||
|
'documentation',
|
||||||
|
'domain',
|
||||||
|
'download',
|
||||||
|
'downloads',
|
||||||
|
'downvote',
|
||||||
|
'draft',
|
||||||
|
'drop',
|
||||||
|
'ecdh-sha2-nistp256',
|
||||||
|
'ecdh-sha2-nistp384',
|
||||||
|
'ecdh-sha2-nistp521',
|
||||||
|
'edit',
|
||||||
|
'editor',
|
||||||
|
'email',
|
||||||
|
'enterprise',
|
||||||
|
'error',
|
||||||
|
'errors',
|
||||||
|
'event',
|
||||||
|
'events',
|
||||||
|
'example',
|
||||||
|
'exception',
|
||||||
|
'exit',
|
||||||
|
'explore',
|
||||||
|
'export',
|
||||||
|
'extensions',
|
||||||
|
'false',
|
||||||
|
'family',
|
||||||
|
'faq',
|
||||||
|
'faqs',
|
||||||
|
'favicon.ico',
|
||||||
|
'features',
|
||||||
|
'feed',
|
||||||
|
'feedback',
|
||||||
|
'feeds',
|
||||||
|
'file',
|
||||||
|
'files',
|
||||||
|
'filter',
|
||||||
|
'follow',
|
||||||
|
'follower',
|
||||||
|
'followers',
|
||||||
|
'following',
|
||||||
|
'fonts',
|
||||||
|
'forgot',
|
||||||
|
'forgot-password',
|
||||||
|
'forgotpassword',
|
||||||
|
'form',
|
||||||
|
'forms',
|
||||||
|
'forum',
|
||||||
|
'forums',
|
||||||
|
'friend',
|
||||||
|
'friends',
|
||||||
|
'ftp',
|
||||||
|
'get',
|
||||||
|
'git',
|
||||||
|
'go',
|
||||||
|
'group',
|
||||||
|
'groups',
|
||||||
|
'guest',
|
||||||
|
'guidelines',
|
||||||
|
'guides',
|
||||||
|
'head',
|
||||||
|
'header',
|
||||||
|
'help',
|
||||||
|
'hide',
|
||||||
|
'hmac-sha',
|
||||||
|
'hmac-sha1',
|
||||||
|
'hmac-sha1-etm',
|
||||||
|
'hmac-sha2-256',
|
||||||
|
'hmac-sha2-256-etm',
|
||||||
|
'hmac-sha2-512',
|
||||||
|
'hmac-sha2-512-etm',
|
||||||
|
'home',
|
||||||
|
'host',
|
||||||
|
'hosting',
|
||||||
|
'hostmaster',
|
||||||
|
'htpasswd',
|
||||||
|
'http',
|
||||||
|
'httpd',
|
||||||
|
'https',
|
||||||
|
'humans.txt',
|
||||||
|
'icons',
|
||||||
|
'images',
|
||||||
|
'imap',
|
||||||
|
'img',
|
||||||
|
'import',
|
||||||
|
'index',
|
||||||
|
'info',
|
||||||
|
'insert',
|
||||||
|
'investors',
|
||||||
|
'invitations',
|
||||||
|
'invite',
|
||||||
|
'invites',
|
||||||
|
'invoice',
|
||||||
|
'is',
|
||||||
|
'isatap',
|
||||||
|
'issues',
|
||||||
|
'it',
|
||||||
|
'jobs',
|
||||||
|
'join',
|
||||||
|
'js',
|
||||||
|
'json',
|
||||||
|
'keybase.txt',
|
||||||
|
'learn',
|
||||||
|
'legal',
|
||||||
|
'license',
|
||||||
|
'licensing',
|
||||||
|
'like',
|
||||||
|
'limit',
|
||||||
|
'live',
|
||||||
|
'load',
|
||||||
|
'local',
|
||||||
|
'localdomain',
|
||||||
|
'localhost',
|
||||||
|
'lock',
|
||||||
|
'login',
|
||||||
|
'logout',
|
||||||
|
'lost-password',
|
||||||
|
'mail',
|
||||||
|
'mail0',
|
||||||
|
'mail1',
|
||||||
|
'mail2',
|
||||||
|
'mail3',
|
||||||
|
'mail4',
|
||||||
|
'mail5',
|
||||||
|
'mail6',
|
||||||
|
'mail7',
|
||||||
|
'mail8',
|
||||||
|
'mail9',
|
||||||
|
'mailer-daemon',
|
||||||
|
'mailerdaemon',
|
||||||
|
'map',
|
||||||
|
'marketing',
|
||||||
|
'marketplace',
|
||||||
|
'master',
|
||||||
|
'me',
|
||||||
|
'media',
|
||||||
|
'member',
|
||||||
|
'members',
|
||||||
|
'message',
|
||||||
|
'messages',
|
||||||
|
'metrics',
|
||||||
|
'mis',
|
||||||
|
'mobile',
|
||||||
|
'moderator',
|
||||||
|
'modify',
|
||||||
|
'more',
|
||||||
|
'mx',
|
||||||
|
'my',
|
||||||
|
'net',
|
||||||
|
'network',
|
||||||
|
'new',
|
||||||
|
'news',
|
||||||
|
'newsletter',
|
||||||
|
'newsletters',
|
||||||
|
'next',
|
||||||
|
'nil',
|
||||||
|
'no-reply',
|
||||||
|
'nobody',
|
||||||
|
'noc',
|
||||||
|
'none',
|
||||||
|
'noreply',
|
||||||
|
'notification',
|
||||||
|
'notifications',
|
||||||
|
'ns',
|
||||||
|
'ns0',
|
||||||
|
'ns1',
|
||||||
|
'ns2',
|
||||||
|
'ns3',
|
||||||
|
'ns4',
|
||||||
|
'ns5',
|
||||||
|
'ns6',
|
||||||
|
'ns7',
|
||||||
|
'ns8',
|
||||||
|
'ns9',
|
||||||
|
'null',
|
||||||
|
'oauth',
|
||||||
|
'oauth2',
|
||||||
|
'offer',
|
||||||
|
'offers',
|
||||||
|
'online',
|
||||||
|
'openid',
|
||||||
|
'order',
|
||||||
|
'orders',
|
||||||
|
'overview',
|
||||||
|
'owner',
|
||||||
|
'page',
|
||||||
|
'pages',
|
||||||
|
'partners',
|
||||||
|
'passwd',
|
||||||
|
'password',
|
||||||
|
'pay',
|
||||||
|
'payment',
|
||||||
|
'payments',
|
||||||
|
'photo',
|
||||||
|
'photos',
|
||||||
|
'pixel',
|
||||||
|
'plans',
|
||||||
|
'plugins',
|
||||||
|
'policies',
|
||||||
|
'policy',
|
||||||
|
'pop',
|
||||||
|
'pop3',
|
||||||
|
'popular',
|
||||||
|
'portfolio',
|
||||||
|
'post',
|
||||||
|
'postfix',
|
||||||
|
'postmaster',
|
||||||
|
'poweruser',
|
||||||
|
'preferences',
|
||||||
|
'premium',
|
||||||
|
'press',
|
||||||
|
'previous',
|
||||||
|
'pricing',
|
||||||
|
'print',
|
||||||
|
'privacy',
|
||||||
|
'privacy-policy',
|
||||||
|
'private',
|
||||||
|
'prod',
|
||||||
|
'product',
|
||||||
|
'production',
|
||||||
|
'profile',
|
||||||
|
'profiles',
|
||||||
|
'project',
|
||||||
|
'projects',
|
||||||
|
'public',
|
||||||
|
'purchase',
|
||||||
|
'put',
|
||||||
|
'quota',
|
||||||
|
'redirect',
|
||||||
|
'reduce',
|
||||||
|
'refund',
|
||||||
|
'refunds',
|
||||||
|
'register',
|
||||||
|
'registration',
|
||||||
|
'remove',
|
||||||
|
'replies',
|
||||||
|
'reply',
|
||||||
|
'report',
|
||||||
|
'request',
|
||||||
|
'request-password',
|
||||||
|
'reset',
|
||||||
|
'reset-password',
|
||||||
|
'response',
|
||||||
|
'return',
|
||||||
|
'returns',
|
||||||
|
'review',
|
||||||
|
'reviews',
|
||||||
|
'robots.txt',
|
||||||
|
'root',
|
||||||
|
'rootuser',
|
||||||
|
'rsa-sha2-2',
|
||||||
|
'rsa-sha2-512',
|
||||||
|
'rss',
|
||||||
|
'rules',
|
||||||
|
'sales',
|
||||||
|
'save',
|
||||||
|
'script',
|
||||||
|
'sdk',
|
||||||
|
'search',
|
||||||
|
'secure',
|
||||||
|
'security',
|
||||||
|
'select',
|
||||||
|
'services',
|
||||||
|
'session',
|
||||||
|
'sessions',
|
||||||
|
'settings',
|
||||||
|
'setup',
|
||||||
|
'share',
|
||||||
|
'shift',
|
||||||
|
'shop',
|
||||||
|
'signin',
|
||||||
|
'signup',
|
||||||
|
'site',
|
||||||
|
'sitemap',
|
||||||
|
'sites',
|
||||||
|
'smtp',
|
||||||
|
'sort',
|
||||||
|
'source',
|
||||||
|
'sql',
|
||||||
|
'ssh',
|
||||||
|
'ssh-rsa',
|
||||||
|
'ssl',
|
||||||
|
'ssladmin',
|
||||||
|
'ssladministrator',
|
||||||
|
'sslwebmaster',
|
||||||
|
'stage',
|
||||||
|
'staging',
|
||||||
|
'stat',
|
||||||
|
'static',
|
||||||
|
'statistics',
|
||||||
|
'stats',
|
||||||
|
'status',
|
||||||
|
'store',
|
||||||
|
'style',
|
||||||
|
'styles',
|
||||||
|
'stylesheet',
|
||||||
|
'stylesheets',
|
||||||
|
'subdomain',
|
||||||
|
'subscribe',
|
||||||
|
'sudo',
|
||||||
|
'super',
|
||||||
|
'superuser',
|
||||||
|
'support',
|
||||||
|
'survey',
|
||||||
|
'sync',
|
||||||
|
'sysadmin',
|
||||||
|
'system',
|
||||||
|
'tablet',
|
||||||
|
'tag',
|
||||||
|
'tags',
|
||||||
|
'team',
|
||||||
|
'telnet',
|
||||||
|
'terms',
|
||||||
|
'terms-of-use',
|
||||||
|
'test',
|
||||||
|
'testimonials',
|
||||||
|
'theme',
|
||||||
|
'themes',
|
||||||
|
'today',
|
||||||
|
'tools',
|
||||||
|
'topic',
|
||||||
|
'topics',
|
||||||
|
'tour',
|
||||||
|
'training',
|
||||||
|
'translate',
|
||||||
|
'translations',
|
||||||
|
'trending',
|
||||||
|
'trial',
|
||||||
|
'true',
|
||||||
|
'umac-128',
|
||||||
|
'umac-128-etm',
|
||||||
|
'umac-64',
|
||||||
|
'umac-64-etm',
|
||||||
|
'undefined',
|
||||||
|
'unfollow',
|
||||||
|
'unlike',
|
||||||
|
'unsubscribe',
|
||||||
|
'update',
|
||||||
|
'upgrade',
|
||||||
|
'usenet',
|
||||||
|
'user',
|
||||||
|
'username',
|
||||||
|
'users',
|
||||||
|
'uucp',
|
||||||
|
'var',
|
||||||
|
'verify',
|
||||||
|
'video',
|
||||||
|
'view',
|
||||||
|
'void',
|
||||||
|
'vote',
|
||||||
|
'webmail',
|
||||||
|
'webmaster',
|
||||||
|
'website',
|
||||||
|
'widget',
|
||||||
|
'widgets',
|
||||||
|
'wiki',
|
||||||
|
'wpad',
|
||||||
|
'write',
|
||||||
|
'www',
|
||||||
|
'www-data',
|
||||||
|
'www1',
|
||||||
|
'www2',
|
||||||
|
'www3',
|
||||||
|
'www4',
|
||||||
|
'you',
|
||||||
|
'yourname',
|
||||||
|
'yourusername',
|
||||||
|
'zlib'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const blocklistedUsernames = [...new Set(blocklist)];
|
||||||
|
Reference in New Issue
Block a user