Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update escape-related helpers #19655

Merged
merged 7 commits into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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