0

I'm trying to run a user-submitted script in a sandbox to process some data, before sending the output to a specified end point through a http request via node-fetch. However, I'm not sure if I am even doing it correctly, even after reading the documentation for VM2, I'm not completely certain of what options I need to configure.

Here is an example, where I call process(); inputData is { a: 123 }, and userScript will be the sampleScript.js shown below.

process(inputData, userScript) {
  const { NodeVM } = require('vm2');
  const vm = new NodeVM({
        console: 'inherit',
        sandbox: { content: inputData },
        require: { external: true },
        wrapper: 'none',
      });
  console.log(vm.run(userScript, 'node_modules'));
}

sampleScript.js

input = content;

function execute(data) {
  data['a'] *= 100;
  const fetch = require('node-fetch');
  await fetch(`webhook.site-endpoint`, {
      method: 'POST',
      body: JSON.stringify(data),
    });
}
execute(input);

I should be expecting a message '12300' on the specified endpoint. However, seems like there is something wrong with the await fetch method call, as I am getting this error on my console:

(node:36376) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:80 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) (node:36376) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode).

It might just be the way I configured the options of the sandbox, as I am not sure if I have successfully imported the node-fetch library in the first place. Any advice would be appreciated!

jun
  • 192
  • 15
  • Port 80 is a privileged port. You cannot connect to it without super user privileges. Try connecting to port higher than 1024. – Abrar Hossain Nov 21 '20 at 09:07
  • hi Abrar, how can I do that? I'm not very sure how it relates to the port since I just issuing a request to a callback url? – jun Nov 21 '20 at 09:25
  • The process your are connecting to on port 80 needs to be killed and then started on another port (say port 3000). It relates to it because you are getting ECONNREFUSED. That happens when either there is no process/server listening on said port or when you try to connect to a privileged port without super user privileges. – Abrar Hossain Nov 21 '20 at 09:28

1 Answers1

0

You successfully imported the module by passing the node_modules as the second argument, given that there is node-fetch in your node_modules.

The error, on the other hand, is saying that there was an error while processing a promise but it was unhandled (await was incorrectly used).

The error is also saying about Connection refused, which means node-fetch tried to connect, so node-fetch is working fine. The problem maybe with the URL.

The problem is with the code, I can see that a few things are wrong.

  1. You are using await inside a function that is not async. Use async function execute(data){} instead
  2. There might probably be an error in the fetch command, you should catch it by wrapping it in a try-catch block

The updated code should look like this

input = content;

async function execute(data) {
  try {
    data['a'] *= 100;
    const fetch = require('node-fetch');
    await fetch(`webhook.site-endpoint`, {
      method: 'POST',
      body: JSON.stringify(data),
    });
  }
  catch(err) {
    console.error(err)
  }
}
execute(input);