Skip to content

Commit

Permalink
Merge pull request #19655 from RocketChat/perf/escape-html
Browse files Browse the repository at this point in the history
Update escape-related helpers
  • Loading branch information
tassoevan committed Nov 25, 2020
2 parents 5269866 + 5be9661 commit 56ece62
Show file tree
Hide file tree
Showing 80 changed files with 432 additions and 306 deletions.
5 changes: 2 additions & 3 deletions app/api/server/lib/users.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import s from 'underscore.string';

import { Users } from '../../../models/server/raw';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { escapeRegExp } from '../../../../lib/escapeRegExp';

export async function findUsersToAutocomplete({ uid, selector }) {
if (!await hasPermissionAsync(uid, 'view-outside-room')) {
Expand All @@ -23,7 +22,7 @@ export async function findUsersToAutocomplete({ uid, selector }) {
limit: 10,
};

const users = await Users.findActiveByUsernameOrNameRegexWithExceptionsAndConditions(new RegExp(s.escapeRegExp(selector.term), 'i'), exceptions, conditions, options).toArray();
const users = await Users.findActiveByUsernameOrNameRegexWithExceptionsAndConditions(new RegExp(escapeRegExp(selector.term), 'i'), exceptions, conditions, options).toArray();

return {
items: users,
Expand Down
8 changes: 4 additions & 4 deletions app/api/server/v1/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { check } from 'meteor/check';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { EJSON } from 'meteor/ejson';
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
import s from 'underscore.string';

import { hasRole, hasPermission } from '../../../authorization/server';
import { Info } from '../../../utils/server';
Expand All @@ -15,6 +14,7 @@ import { API } from '../api';
import { getDefaultUserFields } from '../../../utils/server/functions/getDefaultUserFields';
import { getURL } from '../../../utils/lib/getURL';
import { StdOut } from '../../../logger/server/streamer';
import { escapeHTML } from '../../../../lib/escapeHTML';


// DEPRECATED
Expand Down Expand Up @@ -128,9 +128,9 @@ API.v1.addRoute('shield.svg', { authRequired: false, rateLimiterOptions: { numRe
const width = leftSize + rightSize;
const height = 20;

channel = s.escapeHTML(channel);
text = s.escapeHTML(text);
name = s.escapeHTML(name);
channel = escapeHTML(channel);
text = escapeHTML(text);
name = escapeHTML(name);

return {
headers: { 'Content-Type': 'image/svg+xml;charset=utf-8' },
Expand Down
19 changes: 10 additions & 9 deletions app/authentication/server/startup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Match } from 'meteor/check';
import { Accounts } from 'meteor/accounts-base';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import _ from 'underscore';
import s from 'underscore.string';

import * as Mailer from '../../../mailer/server/api';
import { settings } from '../../../settings/server';
Expand All @@ -18,6 +17,8 @@ import {
} from '../lib/restrictLoginAttempts';
import './settings';
import { getClientAddress } from '../../../../server/lib/getClientAddress';
import { escapeHTML } from '../../../../lib/escapeHTML';
import { escapeRegExp } from '../../../../lib/escapeRegExp';

Accounts.config({
forbidClientAccountCreation: true,
Expand Down Expand Up @@ -47,9 +48,9 @@ Accounts.emailTemplates.userToActivate = {
const email = options.reason ? 'Accounts_Admin_Email_Approval_Needed_With_Reason_Default' : 'Accounts_Admin_Email_Approval_Needed_Default';

return Mailer.replace(TAPi18n.__(email), {
name: s.escapeHTML(options.name),
email: s.escapeHTML(options.email),
reason: s.escapeHTML(options.reason),
name: escapeHTML(options.name),
email: escapeHTML(options.email),
reason: escapeHTML(options.reason),
});
},
};
Expand All @@ -69,7 +70,7 @@ Accounts.emailTemplates.userActivated = {
const action = active ? activated : 'Deactivated';

return Mailer.replace(TAPi18n.__(`Accounts_Email_${ action }`), {
name: s.escapeHTML(name),
name: escapeHTML(name),
});
},
};
Expand Down Expand Up @@ -121,8 +122,8 @@ Accounts.emailTemplates.enrollAccount.subject = function(user) {

Accounts.emailTemplates.enrollAccount.html = function(user = {}/* , url*/) {
return Mailer.replace(enrollAccountTemplate, {
name: s.escapeHTML(user.name),
email: user.emails && user.emails[0] && s.escapeHTML(user.emails[0].address),
name: escapeHTML(user.name),
email: user.emails && user.emails[0] && escapeHTML(user.emails[0].address),
});
};

Expand Down Expand Up @@ -370,15 +371,15 @@ Accounts.validateNewUser(function(user) {
}

let domainWhiteList = settings.get('Accounts_AllowedDomainsList');
if (_.isEmpty(s.trim(domainWhiteList))) {
if (_.isEmpty(domainWhiteList?.trim())) {
return true;
}

domainWhiteList = domainWhiteList.split(',').map((domain) => domain.trim());

if (user.emails && user.emails.length > 0) {
const email = user.emails[0].address;
const inWhiteList = domainWhiteList.some((domain) => email.match(`@${ RegExp.escape(domain) }$`));
const inWhiteList = domainWhiteList.some((domain) => email.match(`@${ escapeRegExp(domain) }$`));

if (inWhiteList === false) {
throw new Meteor.Error('error-invalid-domain');
Expand Down
2 changes: 1 addition & 1 deletion app/autolinker/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Autolinker from 'autolinker';

import { settings } from '../../settings';
import { callbacks } from '../../callbacks';
import { escapeRegExp } from '../../../client/lib/escapeRegExp';
import { escapeRegExp } from '../../../lib/escapeRegExp';

let config;

Expand Down
4 changes: 2 additions & 2 deletions app/autotranslate/server/autotranslate.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Meteor } from 'meteor/meteor';
import _ from 'underscore';
import s from 'underscore.string';

import { settings } from '../../settings';
import { callbacks } from '../../callbacks';
import { Subscriptions, Messages } from '../../models';
import { Markdown } from '../../markdown/server';
import { Logger } from '../../logger';
import { escapeHTML } from '../../../lib/escapeHTML';

const Providers = Symbol('Providers');
const Provider = Symbol('Provider');
Expand Down Expand Up @@ -273,7 +273,7 @@ export class AutoTranslate {
if (message.msg) {
Meteor.defer(() => {
let targetMessage = Object.assign({}, message);
targetMessage.html = s.escapeHTML(String(targetMessage.msg));
targetMessage.html = escapeHTML(String(targetMessage.msg));
targetMessage = this.tokenize(targetMessage);

const translations = this._translateMessage(targetMessage, targetLanguages);
Expand Down
8 changes: 4 additions & 4 deletions app/channel-settings/client/startup/messageTypes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';

import { escapeHTML } from '../../../../lib/escapeHTML';
import { MessageTypes } from '../../../ui-utils';
import { t } from '../../../utils';

Expand All @@ -24,7 +24,7 @@ Meteor.startup(function() {
data(message) {
return {
user_by: message.u && message.u.username,
room_topic: s.escapeHTML(message.msg || `(${ t('None').toLowerCase() })`),
room_topic: escapeHTML(message.msg || `(${ t('None').toLowerCase() })`),
};
},
});
Expand All @@ -48,7 +48,7 @@ Meteor.startup(function() {
data(message) {
return {
user_by: message.u && message.u.username,
room_announcement: s.escapeHTML(message.msg || `(${ t('None').toLowerCase() })`),
room_announcement: escapeHTML(message.msg || `(${ t('None').toLowerCase() })`),
};
},
});
Expand All @@ -60,7 +60,7 @@ Meteor.startup(function() {
data(message) {
return {
user_by: message.u && message.u.username,
room_description: s.escapeHTML(message.msg || `(${ t('None').toLowerCase() })`),
room_description: escapeHTML(message.msg || `(${ t('None').toLowerCase() })`),
};
},
});
Expand Down
2 changes: 1 addition & 1 deletion app/emoji-custom/client/lib/emojiCustom.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { RoomManager } from '../../../ui-utils/client';
import { emoji, EmojiPicker } from '../../../emoji/client';
import { CachedCollectionManager } from '../../../ui-cached-collection/client';
import { APIClient } from '../../../utils/client';
import { escapeRegExp } from '../../../../client/lib/escapeRegExp';
import { escapeRegExp } from '../../../../lib/escapeRegExp';

export const getEmojiUrlFromName = function(name, extension) {
Session.get;
Expand Down
2 changes: 1 addition & 1 deletion app/emoji/client/emojiPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ReactiveDict } from 'meteor/reactive-dict';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { Template } from 'meteor/templating';

import { escapeRegExp } from '../../../client/lib/escapeRegExp';
import { escapeRegExp } from '../../../lib/escapeRegExp';
import '../../theme/client/imports/components/emojiPicker.css';
import { t } from '../../utils/client';
import { EmojiPicker } from './lib/EmojiPicker';
Expand Down
6 changes: 3 additions & 3 deletions app/highlight-words/client/helper.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import s from 'underscore.string';
import { escapeRegExp } from '../../../lib/escapeRegExp';

export const checkHighlightedWordsInUrls = (msg, urlRegex) => msg.match(urlRegex);

Expand All @@ -14,9 +14,9 @@ export const removeHighlightedUrls = (msg, highlight, urlMatches) => {

const highlightTemplate = '$1<span class="highlight-text">$2</span>$3';

export const getRegexHighlight = (highlight) => new RegExp(`(^|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(${ s.escapeRegExp(highlight) })($|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(?![^<]*>|[^<>]*<\\/)`, 'gmi');
export const getRegexHighlight = (highlight) => new RegExp(`(^|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(${ escapeRegExp(highlight) })($|\\b|[\\s\\n\\r\\t.,،'\\\"\\+!?:-])(?![^<]*>|[^<>]*<\\/)`, 'gmi');

export const getRegexHighlightUrl = (highlight) => new RegExp(`https?:\/\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)(${ s.escapeRegExp(highlight) })\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)`, 'gmi');
export const getRegexHighlightUrl = (highlight) => new RegExp(`https?:\/\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)(${ escapeRegExp(highlight) })\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)`, 'gmi');

export const highlightWords = (msg, highlights) => highlights.reduce((msg, { highlight, regex, urlRegex }) => {
const urlMatches = checkHighlightedWordsInUrls(msg, urlRegex);
Expand Down
6 changes: 4 additions & 2 deletions app/katex/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Tracker } from 'meteor/tracker';
import _ from 'underscore';
import s from 'underscore.string';

import { escapeHTML } from '../../../lib/escapeHTML';
import { unescapeHTML } from '../../../lib/unescapeHTML';
import { callbacks } from '../../callbacks';
import { settings } from '../../settings';

Expand Down Expand Up @@ -109,7 +111,7 @@ class Katex {
const before = str.substr(0, match.outer.start);
const after = str.substr(match.outer.end);
let latex = match.inner.extract(str);
latex = s.unescapeHTML(latex);
latex = unescapeHTML(latex);
return {
before,
latex,
Expand All @@ -129,7 +131,7 @@ class Katex {
});
} catch ({ message }) {
return `<div class="katex-error katex-${ displayMode ? 'block' : 'inline' }-error">`
+ `${ s.escapeHTML(message) }</div>`;
+ `${ escapeHTML(message) }</div>`;
}
}

Expand Down
4 changes: 3 additions & 1 deletion app/lib/server/functions/checkEmailAvailability.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';

import { escapeRegExp } from '../../../../lib/escapeRegExp';

export const checkEmailAvailability = function(email) {
return !Meteor.users.findOne({ 'emails.address': { $regex: new RegExp(`^${ s.trim(s.escapeRegExp(email)) }$`, 'i') } });
return !Meteor.users.findOne({ 'emails.address': { $regex: new RegExp(`^${ s.trim(escapeRegExp(email)) }$`, 'i') } });
};
5 changes: 3 additions & 2 deletions app/lib/server/functions/checkUsernameAvailability.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';

import { escapeRegExp } from '../../../../lib/escapeRegExp';
import { settings } from '../../../settings';

let usernameBlackList = [];

const toRegExp = (username) => new RegExp(`^${ s.escapeRegExp(username).trim() }$`, 'i');
const toRegExp = (username) => new RegExp(`^${ escapeRegExp(username).trim() }$`, 'i');

settings.get('Accounts_BlockedUsernameList', (key, value) => {
usernameBlackList = ['all', 'here'].concat(value.split(',')).map(toRegExp);
});

const usernameIsBlocked = (username, usernameBlackList) => usernameBlackList.length
&& usernameBlackList.some((restrictedUsername) => restrictedUsername.test(s.trim(s.escapeRegExp(username))));
&& usernameBlackList.some((restrictedUsername) => restrictedUsername.test(s.trim(escapeRegExp(username))));

export const checkUsernameAvailability = function(username) {
if (usernameIsBlocked(username, usernameBlackList)) {
Expand Down
3 changes: 2 additions & 1 deletion app/lib/server/functions/getFullUserData.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Logger } from '../../../logger';
import { settings } from '../../../settings';
import { Users } from '../../../models/server';
import { hasPermission } from '../../../authorization';
import { escapeRegExp } from '../../../../lib/escapeRegExp';

const logger = new Logger('getFullUserData');

Expand Down Expand Up @@ -129,6 +130,6 @@ export const getFullUserData = function({ userId, filter, limit: l }) {
return Users.findByUsername(userToRetrieveFullUserData.username, options);
}

const usernameReg = new RegExp(s.escapeRegExp(username), 'i');
const usernameReg = new RegExp(escapeRegExp(username), 'i');
return Users.findByUsernameNameOrEmailAddress(usernameReg, options);
};
15 changes: 8 additions & 7 deletions app/lib/server/functions/notifications/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { roomTypes } from '../../../../utils';
import { metrics } from '../../../../metrics';
import { callbacks } from '../../../../callbacks';
import { getURL } from '../../../../utils/server';
import { escapeHTML } from '../../../../../lib/escapeHTML';

let advice = '';
let goToMessage = '';
Expand All @@ -23,8 +24,8 @@ Meteor.startup(() => {
function getEmailContent({ message, user, room }) {
const lng = (user && user.language) || settings.get('Language') || 'en';

const roomName = s.escapeHTML(`#${ roomTypes.getRoomName(room.t, room) }`);
const userName = s.escapeHTML(settings.get('UI_Use_Real_Name') ? message.u.name || message.u.username : message.u.username);
const roomName = escapeHTML(`#${ roomTypes.getRoomName(room.t, room) }`);
const userName = escapeHTML(settings.get('UI_Use_Real_Name') ? message.u.name || message.u.username : message.u.username);

const roomType = roomTypes.getConfig(room.t);

Expand All @@ -39,7 +40,7 @@ function getEmailContent({ message, user, room }) {
return header;
}

let messageContent = s.escapeHTML(message.msg);
let messageContent = escapeHTML(message.msg);

if (message.t === 'e2e') {
messageContent = TAPi18n.__('Encrypted_message', { lng });
Expand All @@ -66,10 +67,10 @@ function getEmailContent({ message, user, room }) {
return fileHeader;
}

let content = `${ s.escapeHTML(message.file.name) }`;
let content = `${ escapeHTML(message.file.name) }`;

if (message.attachments && message.attachments.length === 1 && message.attachments[0].description !== '') {
content += `<br/><br/>${ s.escapeHTML(message.attachments[0].description) }`;
content += `<br/><br/>${ escapeHTML(message.attachments[0].description) }`;
}

return `${ fileHeader }:<br/><br/>${ content }`;
Expand All @@ -85,10 +86,10 @@ function getEmailContent({ message, user, room }) {
let content = '';

if (attachment.title) {
content += `${ s.escapeHTML(attachment.title) }<br/>`;
content += `${ escapeHTML(attachment.title) }<br/>`;
}
if (attachment.text) {
content += `${ s.escapeHTML(attachment.text) }<br/>`;
content += `${ escapeHTML(attachment.text) }<br/>`;
}

return `${ header }:<br/><br/>${ content }`;
Expand Down
6 changes: 3 additions & 3 deletions app/lib/server/functions/notifications/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import s from 'underscore.string';

import { escapeRegExp } from '../../../../../lib/escapeRegExp';
import { callbacks } from '../../../../callbacks';
import { settings } from '../../../../settings';

Expand Down Expand Up @@ -39,7 +39,7 @@ export function replaceMentionedUsernamesWithFullNames(message, mentions) {
}
mentions.forEach((mention) => {
if (mention.name) {
message = message.replace(new RegExp(s.escapeRegExp(`@${ mention.username }`), 'g'), mention.name);
message = message.replace(new RegExp(escapeRegExp(`@${ mention.username }`), 'g'), mention.name);
}
});
return message;
Expand All @@ -57,7 +57,7 @@ export function messageContainsHighlight(message, highlights) {
if (! highlights || highlights.length === 0) { return false; }

return highlights.some(function(highlight) {
const regexp = new RegExp(s.escapeRegExp(highlight), 'i');
const regexp = new RegExp(escapeRegExp(highlight), 'i');
return regexp.test(message.msg);
});
}
Expand Down
7 changes: 4 additions & 3 deletions app/lib/server/functions/saveUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { passwordPolicy } from '../lib/passwordPolicy';
import { validateEmailDomain } from '../lib';
import { validateUserRoles } from '../../../../ee/app/authorization/server/validateUserRoles';
import { saveUserIdentity } from './saveUserIdentity';
import { escapeHTML } from '../../../../lib/escapeHTML';

import { checkEmailAvailability, checkUsernameAvailability, setUserAvatar, setEmail, setStatusText } from '.';

Expand All @@ -33,13 +34,13 @@ function _sendUserEmail(subject, html, userData) {
subject,
html,
data: {
email: s.escapeHTML(userData.email),
password: s.escapeHTML(userData.password),
email: escapeHTML(userData.email),
password: escapeHTML(userData.password),
},
};

if (typeof userData.name !== 'undefined') {
email.data.name = s.escapeHTML(userData.name);
email.data.name = escapeHTML(userData.name);
}

try {
Expand Down

0 comments on commit 56ece62

Please sign in to comment.