fix(core): Prevent expressions XSS (#3366)

*  Added checks for window object access in template strings.

*  Added self, prompt and confirm to blocklist. Changed window usage condition.
This commit is contained in:
Alex Grozav 2022-05-27 18:00:51 +03:00 committed by GitHub
parent 1910299a88
commit 993554f22a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -118,6 +118,26 @@ export class Expression {
// @ts-ignore // @ts-ignore
data.document = {}; data.document = {};
data.global = {};
data.window = {};
data.Window = {};
data.this = {};
data.self = {};
// Alerts
data.alert = {};
data.prompt = {};
data.confirm = {};
// Prevent Remote Code Execution
data.eval = {};
data.setTimeout = {};
data.setInterval = {};
data.Function = {};
// Prevent requests
data.fetch = {};
data.XMLHttpRequest = {};
// @ts-ignore // @ts-ignore
data.DateTime = DateTime; data.DateTime = DateTime;
@ -129,8 +149,13 @@ export class Expression {
// Execute the expression // Execute the expression
try { try {
if (/([^a-zA-Z0-9"']window[^a-zA-Z0-9"'])/g.test(parameterValue)) {
throw new Error(`window is not allowed`);
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
const returnValue = tmpl.tmpl(parameterValue, data); const returnValue = tmpl.tmpl(parameterValue, data);
if (typeof returnValue === 'function') { if (typeof returnValue === 'function') {
throw new Error('Expression resolved to a function. Please add "()"'); throw new Error('Expression resolved to a function. Please add "()"');
} else if (returnValue !== null && typeof returnValue === 'object') { } else if (returnValue !== null && typeof returnValue === 'object') {
@ -368,6 +393,7 @@ export class Expression {
if (parameterValue === null || parameterValue === undefined) { if (parameterValue === null || parameterValue === undefined) {
return parameterValue; return parameterValue;
} }
// Data is an object // Data is an object
const returnData: INodeParameters = {}; const returnData: INodeParameters = {};
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
@ -381,6 +407,7 @@ export class Expression {
if (returnObjectAsString && typeof returnData === 'object') { if (returnObjectAsString && typeof returnData === 'object') {
return this.convertObjectValueToString(returnData); return this.convertObjectValueToString(returnData);
} }
return returnData; return returnData;
} }
} }