Skip to content
Snippets Groups Projects
Unverified Commit 6f3133f4 authored by Rodrigo Nascimento's avatar Rodrigo Nascimento Committed by GitHub
Browse files

Chore: Increase performance and security of integrations’ scripts (#25641)

parent cbb0844c
No related branches found
No related tags found
No related merge requests found
import vm from 'vm';
import { VM, VMScript } from 'vm2';
import { Meteor } from 'meteor/meteor';
import { HTTP } from 'meteor/http';
import { Random } from 'meteor/random';
......@@ -71,11 +70,16 @@ function getIntegrationScript(integration) {
incomingLogger.info({ msg: 'Will evaluate script of Trigger', name: integration.name });
incomingLogger.debug(script);
const vmScript = vm.createScript(script, 'script.js');
vmScript.runInNewContext(sandbox);
if (sandbox.Script) {
const vmScript = new VMScript(`${script}; Script;`, 'script.js');
const vm = new VM({
sandbox,
});
const ScriptClass = vm.run(vmScript);
if (ScriptClass) {
compiledScripts[integration._id] = {
script: new sandbox.Script(),
script: new ScriptClass(),
store,
_updatedAt: integration._updatedAt,
};
......@@ -92,10 +96,8 @@ function getIntegrationScript(integration) {
throw API.v1.failure('error-evaluating-script');
}
if (!sandbox.Script) {
incomingLogger.error({ msg: 'Class "Script" not in Trigger', name: integration.name });
throw API.v1.failure('class-script-not-found');
}
incomingLogger.error({ msg: 'Class "Script" not in Trigger', name: integration.name });
throw API.v1.failure('class-script-not-found');
}
function createIntegration(options, user) {
......@@ -205,9 +207,12 @@ function executeIntegrationRest() {
sandbox.script = script;
sandbox.request = request;
const result = Future.fromPromise(
vm.runInNewContext(
`
const vm = new VM({
timeout: 3000,
sandbox,
});
const scriptResult = vm.run(`
new Promise((resolve, reject) => {
Fiber(() => {
scriptTimeout(reject);
......@@ -218,13 +223,9 @@ function executeIntegrationRest() {
}
}).run();
}).catch((error) => { throw new Error(error); });
`,
sandbox,
{
timeout: 3000,
},
),
).wait();
`);
const result = Future.fromPromise(scriptResult).wait();
if (!result) {
incomingLogger.debug({
......
import vm from 'vm';
import { VM, VMScript } from 'vm2';
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random';
import { HTTP } from 'meteor/http';
......@@ -19,7 +18,6 @@ import { fetch } from '../../../../server/lib/http/fetch';
export class RocketChatIntegrationHandler {
constructor() {
this.vm = vm;
this.successResults = [200, 201, 202];
this.compiledScripts = {};
this.triggers = {};
......@@ -275,18 +273,20 @@ export class RocketChatIntegrationHandler {
const script = integration.scriptCompiled;
const { store, sandbox } = this.buildSandbox();
let vmScript;
try {
outgoingLogger.info({ msg: 'Will evaluate script of Trigger', name: integration.name });
outgoingLogger.debug(script);
vmScript = this.vm.createScript(script, 'script.js');
const vmScript = new VMScript(`${script}; Script;`, 'script.js');
const vm = new VM({
sandbox,
});
vmScript.runInNewContext(sandbox);
const ScriptClass = vm.run(vmScript);
if (sandbox.Script) {
if (ScriptClass) {
this.compiledScripts[integration._id] = {
script: new sandbox.Script(),
script: new ScriptClass(),
store,
_updatedAt: integration._updatedAt,
};
......@@ -303,10 +303,8 @@ export class RocketChatIntegrationHandler {
throw new Meteor.Error('error-evaluating-script');
}
if (!sandbox.Script) {
outgoingLogger.error(`Class "Script" not in Trigger ${integration.name}:`);
throw new Meteor.Error('class-script-not-found');
}
outgoingLogger.error(`Class "Script" not in Trigger ${integration.name}:`);
throw new Meteor.Error('class-script-not-found');
}
hasScriptAndMethod(integration, method) {
......@@ -352,9 +350,12 @@ export class RocketChatIntegrationHandler {
this.updateHistory({ historyId, step: `execute-script-before-running-${method}` });
const result = Future.fromPromise(
this.vm.runInNewContext(
`
const vm = new VM({
timeout: 3000,
sandbox,
});
const scriptResult = vm.run(`
new Promise((resolve, reject) => {
Fiber(() => {
scriptTimeout(reject);
......@@ -365,13 +366,9 @@ export class RocketChatIntegrationHandler {
}
}).run();
}).catch((error) => { throw new Error(error); });
`,
sandbox,
{
timeout: 3000,
},
),
).wait();
`);
const result = Future.fromPromise(scriptResult).wait();
outgoingLogger.debug({
msg: `Script method "${method}" result of the Integration "${integration.name}" is:`,
......
......@@ -350,6 +350,7 @@
"url-polyfill": "^1.1.12",
"use-subscription": "~1.6.0",
"uuid": "^8.3.2",
"vm2": "^3.9.9",
"webdav": "^4.9.0",
"xml-crypto": "^2.1.3",
"xml-encryption": "2.0.0",
......
......@@ -4989,6 +4989,7 @@ __metadata:
url-polyfill: ^1.1.12
use-subscription: ~1.6.0
uuid: ^8.3.2
vm2: ^3.9.9
webdav: ^4.9.0
webpack: ^4.46.0
xml-crypto: ^2.1.3
......@@ -33987,7 +33988,7 @@ __metadata:
languageName: node
linkType: hard
 
"vm2@npm:^3.9.8":
"vm2@npm:^3.9.8, vm2@npm:^3.9.9":
version: 3.9.9
resolution: "vm2@npm:3.9.9"
dependencies:
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment