mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 04:47:29 -08:00
fix(core): Disallow code generation in task runner (#12522)
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
This commit is contained in:
parent
46f13cfca9
commit
35b618098b
|
@ -4,7 +4,10 @@
|
|||
"runner-type": "javascript",
|
||||
"workdir": "/home/node",
|
||||
"command": "/usr/local/bin/node",
|
||||
"args": ["/usr/local/lib/node_modules/n8n/node_modules/@n8n/task-runner/dist/start.js"],
|
||||
"args": [
|
||||
"--disallow-code-generation-from-strings",
|
||||
"/usr/local/lib/node_modules/n8n/node_modules/@n8n/task-runner/dist/start.js"
|
||||
],
|
||||
"allowed-env": [
|
||||
"PATH",
|
||||
"GENERIC_TIMEZONE",
|
||||
|
|
|
@ -302,6 +302,7 @@ describe('JsTaskRunner', () => {
|
|||
['typeof clearInterval', 'function'],
|
||||
['typeof clearImmediate', 'function'],
|
||||
],
|
||||
eval: [['eval("1+2")', 3]],
|
||||
'JS built-ins': [
|
||||
['typeof btoa', 'function'],
|
||||
['typeof atob', 'function'],
|
||||
|
|
|
@ -19,7 +19,7 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import * as a from 'node:assert';
|
||||
import { inspect } from 'node:util';
|
||||
import { runInNewContext, type Context } from 'node:vm';
|
||||
import { type Context, createContext, runInContext } from 'node:vm';
|
||||
|
||||
import type { MainConfig } from '@/config/main-config';
|
||||
import { UnsupportedFunctionError } from '@/js-task-runner/errors/unsupported-function.error';
|
||||
|
@ -158,10 +158,8 @@ export class JsTaskRunner extends TaskRunner {
|
|||
|
||||
private getNativeVariables() {
|
||||
return {
|
||||
// Exposed Node.js globals in vm2
|
||||
// Exposed Node.js globals
|
||||
Buffer,
|
||||
Function,
|
||||
eval,
|
||||
setTimeout,
|
||||
setInterval,
|
||||
setImmediate,
|
||||
|
@ -205,7 +203,7 @@ export class JsTaskRunner extends TaskRunner {
|
|||
|
||||
signal.addEventListener('abort', abortHandler, { once: true });
|
||||
|
||||
const taskResult = runInNewContext(
|
||||
const taskResult = runInContext(
|
||||
`globalThis.global = globalThis; module.exports = async function VmCodeWrapper() {${settings.code}\n}()`,
|
||||
context,
|
||||
{ timeout: this.taskTimeout * 1000 },
|
||||
|
@ -268,7 +266,7 @@ export class JsTaskRunner extends TaskRunner {
|
|||
|
||||
signal.addEventListener('abort', abortHandler);
|
||||
|
||||
const taskResult = runInNewContext(
|
||||
const taskResult = runInContext(
|
||||
`module.exports = async function VmCodeWrapper() {${settings.code}\n}()`,
|
||||
context,
|
||||
{ timeout: this.taskTimeout * 1000 },
|
||||
|
@ -470,7 +468,7 @@ export class JsTaskRunner extends TaskRunner {
|
|||
dataProxy: IWorkflowDataProxyData,
|
||||
additionalProperties: Record<string, unknown> = {},
|
||||
): Context {
|
||||
const context: Context = {
|
||||
return createContext({
|
||||
[inspect.custom]: () => '[[ExecutionContext]]',
|
||||
require: this.requireResolver,
|
||||
module: {},
|
||||
|
@ -480,8 +478,6 @@ export class JsTaskRunner extends TaskRunner {
|
|||
...dataProxy,
|
||||
...this.buildRpcCallObject(taskId),
|
||||
...additionalProperties,
|
||||
};
|
||||
|
||||
return context;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,5 +117,16 @@ describe('TaskRunnerProcess', () => {
|
|||
const options = spawnMock.mock.calls[0][2] as SpawnOptions;
|
||||
expect(options.env).not.toHaveProperty('NODE_OPTIONS');
|
||||
});
|
||||
|
||||
it('should use --disallow-code-generation-from-strings flag', async () => {
|
||||
jest.spyOn(authService, 'createGrantToken').mockResolvedValue('grantToken');
|
||||
|
||||
await taskRunnerProcess.start();
|
||||
|
||||
expect(spawnMock.mock.calls[0].at(1)).toEqual([
|
||||
'--disallow-code-generation-from-strings',
|
||||
expect.stringContaining('/packages/@n8n/task-runner/dist/start.js'),
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -106,7 +106,7 @@ export class TaskRunnerProcess extends TypedEmitter<TaskRunnerProcessEventMap> {
|
|||
startNode(grantToken: string, taskBrokerUri: string) {
|
||||
const startScript = require.resolve('@n8n/task-runner/start');
|
||||
|
||||
return spawn('node', [startScript], {
|
||||
return spawn('node', ['--disallow-code-generation-from-strings', startScript], {
|
||||
env: this.getProcessEnvVars(grantToken, taskBrokerUri),
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue