sanitizeShellString() and other security improvements

This commit is contained in:
Sebastian Hildebrandt 2021-03-15 11:21:32 +01:00
parent b106e41538
commit 7922366d70
11 changed files with 95 additions and 37 deletions

View File

@ -77,7 +77,8 @@ For major (breaking) changes - **version 4, 3 and 2** - see end of page.
| Version | Date | Comment | | Version | Date | Comment |
| -------------- | -------------- | -------- | | -------------- | -------------- | -------- |
| 5.6.3 | 2021-03-10 | `sanitizeShellString()` improvement | | 5.6.4 | 2021-03-15 | `sanitizeShellString()` and other security improvements |
| 5.6.3 | 2021-03-14 | `sanitizeShellString()` improvement |
| 5.6.2 | 2021-03-10 | `networkInterfaces()` `cpu()` improvement (win) | | 5.6.2 | 2021-03-10 | `networkInterfaces()` `cpu()` improvement (win) |
| 5.6.1 | 2021-03-03 | `get()` fixed issue boolean parameters | | 5.6.1 | 2021-03-03 | `get()` fixed issue boolean parameters |
| 5.6.0 | 2021-03-03 | `cpuTemperature()` added socket and chipset temp (linux) | | 5.6.0 | 2021-03-03 | `cpuTemperature()` added socket and chipset temp (linux) |

View File

@ -56,6 +56,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr>
<th scope="row">5.6.4</th>
<td>2021-03-15</td>
<td><span class="code">sanitizeShellString()</span> and other security improvements</td>
</tr>
<tr> <tr>
<th scope="row">5.6.3</th> <th scope="row">5.6.3</th>
<td>2021-03-14</td> <td>2021-03-14</td>

View File

@ -166,11 +166,11 @@
<body> <body>
<header class="bg-image-full"> <header class="bg-image-full">
<div class="top-container"> <div class="top-container">
<a href="security.html" class="recommendation">Security advisory:<br>Update to v5.6.3</a> <a href="security.html" class="recommendation">Security advisory:<br>Update to v5.6.4</a>
<img class="logo" src="assets/logo.png"> <img class="logo" src="assets/logo.png">
<div class="title">systeminformation</div> <div class="title">systeminformation</div>
<div class="subtitle"><span id="typed"></span>&nbsp;</div> <div class="subtitle"><span id="typed"></span>&nbsp;</div>
<div class="version">New Version: <span id="version">5.6.3</span></div> <div class="version">New Version: <span id="version">5.6.4</span></div>
<button class="btn btn-light" onclick="location.href='https://github.com/sebhildebrandt/systeminformation'">View on Github <i class=" fab fa-github"></i></button> <button class="btn btn-light" onclick="location.href='https://github.com/sebhildebrandt/systeminformation'">View on Github <i class=" fab fa-github"></i></button>
</div> </div>
<div class="down"> <div class="down">

View File

@ -45,8 +45,8 @@
<div class="text"> <div class="text">
<h2>Command Injection Vulnerability</h2> <h2>Command Injection Vulnerability</h2>
<p><span class="bold">Affected versions:</span> <p><span class="bold">Affected versions:</span>
&lt; 5.6.3 and &lt; 4.34.16<br> &lt; 5.6.4 and &lt; 4.34.17<br>
<span class="bold">Date:</span> 2021-03-14<br> <span class="bold">Date:</span> 2021-03-15<br>
<span class="bold">CVE indentifier</span> - <span class="bold">CVE indentifier</span> -
</p> </p>
@ -54,7 +54,7 @@
<p>We had an issue that there was a possibility to perform a potential command injection possibility by passing a manipulated string prototype as a parameter to the following functions. Affected commands: <span class="code">inetLatency()</span>, <span class="code">inetChecksite()</span>, <span class="code">services()</span>, <span class="code">processLoad()</span>.</p> <p>We had an issue that there was a possibility to perform a potential command injection possibility by passing a manipulated string prototype as a parameter to the following functions. Affected commands: <span class="code">inetLatency()</span>, <span class="code">inetChecksite()</span>, <span class="code">services()</span>, <span class="code">processLoad()</span>.</p>
<h4>Patch</h4> <h4>Patch</h4>
<p>Problem was fixed with additional parameter checking. Please upgrade to version >= 5.6.3 (or >= 4.34.16 if you are using version 4).</p> <p>Problem was fixed with additional parameter checking. Please upgrade to version >= 5.6.4 (or >= 4.34.17 if you are using version 4).</p>
<h4>Workarround</h4> <h4>Workarround</h4>
<p>If you cannot upgrade, be sure to check or sanitize parameter strings that are passed to <span class="code">inetLatency()</span>, <span class="code">inetChecksite()</span>, <span class="code">services()</span>, <span class="code">processLoad()</span> (string only)</p> <p>If you cannot upgrade, be sure to check or sanitize parameter strings that are passed to <span class="code">inetLatency()</span>, <span class="code">inetChecksite()</span>, <span class="code">services()</span>, <span class="code">processLoad()</span> (string only)</p>

View File

@ -83,6 +83,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr>
<th scope="row">4.34.17</th>
<td>2021-03-14</td>
<td><span class="code">sanitizeShellString()</span> and other security improvements</td>
</tr>
<tr> <tr>
<th scope="row">4.34.16</th> <th scope="row">4.34.16</th>
<td>2021-03-14</td> <td>2021-03-14</td>

View File

@ -165,12 +165,12 @@
<body> <body>
<header class="bg-image-full"> <header class="bg-image-full">
<div class="container"> <div class="container">
<a href="security.html" class="recommendation">Security advisory:<br>Update to v4.34.16</a> <a href="security.html" class="recommendation">Security advisory:<br>Update to v4.34.17</a>
<img class="logo" src="assets/logo.png"> <img class="logo" src="assets/logo.png">
<div class="title">systeminformation </div> <div class="title">systeminformation </div>
<div class="subtitle"><span id="typed"></span>&nbsp;</div> <div class="subtitle"><span id="typed"></span>&nbsp;</div>
<div class="version larger">Version 4 documentation</div> <div class="version larger">Version 4 documentation</div>
<div class="version">Current Version: <span id="version">4.34.16</span></div> <div class="version">Current Version: <span id="version">4.34.17</span></div>
<button class="btn btn-light" onclick="location.href='https://github.com/sebhildebrandt/systeminformation'">View on Github <i class=" fab fa-github"></i></button> <button class="btn btn-light" onclick="location.href='https://github.com/sebhildebrandt/systeminformation'">View on Github <i class=" fab fa-github"></i></button>
</div> </div>
<div class="down"> <div class="down">

View File

@ -44,8 +44,8 @@
<div class="text"> <div class="text">
<h2>Command Injection Vulnerability</h2> <h2>Command Injection Vulnerability</h2>
<p><span class="bold">Affected versions:</span> <p><span class="bold">Affected versions:</span>
&lt; 4.34.13<br> &lt; 4.34.17<br>
<span class="bold">Date:</span> 2021-03-14<br> <span class="bold">Date:</span> 2021-03-15<br>
<span class="bold">CVE indentifier</span> - <span class="bold">CVE indentifier</span> -
</p> </p>
@ -53,7 +53,7 @@
<p>We had an issue that there was a possibility to perform a potential command injection possibility by passing a manipulated string prototype as a parameter to the following functions. Affected commands: <span class="code">inetLatency()</span>, <span class="code">inetChecksite()</span>, <span class="code">services()</span>, <span class="code">processLoad()</span>.</p> <p>We had an issue that there was a possibility to perform a potential command injection possibility by passing a manipulated string prototype as a parameter to the following functions. Affected commands: <span class="code">inetLatency()</span>, <span class="code">inetChecksite()</span>, <span class="code">services()</span>, <span class="code">processLoad()</span>.</p>
<h4>Patch</h4> <h4>Patch</h4>
<p>Problem was fixed with additional parameter checking. Please upgrade to version >= 4.34.13 if you are using version 4.</p> <p>Problem was fixed with additional parameter checking. Please upgrade to version >= 4.34.17 if you are using version 4.</p>
<h4>Workarround</h4> <h4>Workarround</h4>
<p>If you cannot upgrade, be sure to check or sanitize parameter strings that are passed to <span class="code">inetLatency()</span>, <span class="code">inetChecksite()</span>, <span class="code">services()</span>, <span class="code">processLoad()</span> (string only)</p> <p>If you cannot upgrade, be sure to check or sanitize parameter strings that are passed to <span class="code">inetLatency()</span>, <span class="code">inetChecksite()</span>, <span class="code">services()</span>, <span class="code">processLoad()</span> (string only)</p>

View File

@ -13,7 +13,7 @@
// 12. Internet // 12. Internet
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
const exec = require('child_process').exec; // const exec = require('child_process').exec;
const execFile = require('child_process').execFile; const execFile = require('child_process').execFile;
const util = require('./util'); const util = require('./util');
@ -46,11 +46,12 @@ function inetChecksite(url, callback) {
} }
let urlSanitized = ''; let urlSanitized = '';
const s = util.sanitizeShellString(url, true); const s = util.sanitizeShellString(url, true);
for (let i = 0; i <= 2000; i++) { const mathMin = util.mathMin;
for (let i = 0; i <= mathMin(s.length, 2000); i++) {
if (!(s[i] === undefined)) { if (!(s[i] === undefined)) {
s[i].__proto__.toLowerCase = util.stringToLower; s[i].__proto__.toLowerCase = util.stringToLower;
const sl = s[i].toLowerCase(); const sl = s[i].toLowerCase();
if (sl && sl[0] && !sl[1]) { if (sl && sl[0] && !sl[1] && sl[0].length === 1) {
urlSanitized = urlSanitized + sl[0]; urlSanitized = urlSanitized + sl[0];
} }
} }
@ -65,12 +66,14 @@ function inetChecksite(url, callback) {
} }
let t = Date.now(); let t = Date.now();
if (_linux || _freebsd || _openbsd || _netbsd || _darwin || _sunos) { if (_linux || _freebsd || _openbsd || _netbsd || _darwin || _sunos) {
let args = ' -I --connect-timeout 5 -m 5 ' + urlSanitized + ' 2>/dev/null | head -n 1 | cut -d " " -f2'; let args = ['-I', '--connect-timeout', '5', '-m', '5'];
args.push(urlSanitized);
let cmd = 'curl'; let cmd = 'curl';
exec(cmd + args, function (error, stdout) { util.execSave(cmd, args).then((stdout) => {
let statusCode = parseInt(stdout.toString()); const lines = stdout.split('\n');
let statusCode = lines[0] && lines[0].indexOf(' ') >= 0 ? parseInt(lines[0].split(' ')[1], 10) : 404;
result.status = statusCode || 404; result.status = statusCode || 404;
result.ok = !error && (statusCode === 200 || statusCode === 301 || statusCode === 302 || statusCode === 304); result.ok = (statusCode === 200 || statusCode === 301 || statusCode === 302 || statusCode === 304);
result.ms = (result.ok ? Date.now() - t : null); result.ms = (result.ok ? Date.now() - t : null);
if (callback) { callback(result); } if (callback) { callback(result); }
resolve(result); resolve(result);
@ -142,7 +145,8 @@ function inetLatency(host, callback) {
} }
let hostSanitized = ''; let hostSanitized = '';
const s = (util.isPrototypePolluted() ? '8.8.8.8' : util.sanitizeShellString(host, true)).trim(); const s = (util.isPrototypePolluted() ? '8.8.8.8' : util.sanitizeShellString(host, true)).trim();
for (let i = 0; i <= 2000; i++) { const mathMin = util.mathMin;
for (let i = 0; i <= mathMin(s.length, 2000); i++) {
if (!(s[i] === undefined)) { if (!(s[i] === undefined)) {
s[i].__proto__.toLowerCase = util.stringToLower; s[i].__proto__.toLowerCase = util.stringToLower;
const sl = s[i].toLowerCase(); const sl = s[i].toLowerCase();
@ -171,10 +175,10 @@ function inetLatency(host, callback) {
params = '-c2 -t3 ' + hostSanitized; params = '-c2 -t3 ' + hostSanitized;
filt = 'avg'; filt = 'avg';
} }
execFile('ping', params.split(' '), function (error, stdout) { util.execSave('ping', params.split(' ')).then((stdout) => {
let result = null; let result = null;
if (!error) { if (stdout) {
const lines = stdout.toString().split('\n').filter(line => line.indexOf(filt) >= 0).join('\n'); const lines = stdout.split('\n').filter(line => line.indexOf(filt) >= 0).join('\n');
const line = lines.split('='); const line = lines.split('=');
if (line.length > 1) { if (line.length > 1) {
@ -191,10 +195,10 @@ function inetLatency(host, callback) {
if (_sunos) { if (_sunos) {
const params = '-s -a ' + hostSanitized + ' 56 2'; const params = '-s -a ' + hostSanitized + ' 56 2';
const filt = 'avg'; const filt = 'avg';
execFile('ping', params.split(' '), { timeout: 3000 }, function (error, stdout) { util.execSave('ping', params.split(' '), { timeout: 3000 }).then((stdout) => {
let result = null; let result = null;
if (!error) { if (stdout) {
const lines = stdout.toString().split('\n').filter(line => line.indexOf(filt) >= 0).join('\n'); const lines = stdout.split('\n').filter(line => line.indexOf(filt) >= 0).join('\n');
const line = lines.split('='); const line = lines.split('=');
if (line.length > 1) { if (line.length > 1) {
const parts = line[1].split('/'); const parts = line[1].split('/');

View File

@ -1061,7 +1061,8 @@ function networkStatsSingle(iface) {
process.nextTick(() => { process.nextTick(() => {
let ifaceSanitized = ''; let ifaceSanitized = '';
const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(iface); const s = util.isPrototypePolluted() ? '---' : util.sanitizeShellString(iface);
for (let i = 0; i <= 2000; i++) { const mathMin = util.mathMin;
for (let i = 0; i <= mathMin(s.length, 2000); i++) {
if (!(s[i] === undefined)) { if (!(s[i] === undefined)) {
ifaceSanitized = ifaceSanitized + s[i]; ifaceSanitized = ifaceSanitized + s[i];
} }

View File

@ -111,7 +111,8 @@ function services(srv, callback) {
srvString.__proto__.trim = util.stringTrim; srvString.__proto__.trim = util.stringTrim;
const s = util.sanitizeShellString(srv); const s = util.sanitizeShellString(srv);
for (let i = 0; i <= 2000; i++) { const mathMin = util.mathMin;
for (let i = 0; i <= mathMin(s.length, 2000); i++) {
if (!(s[i] === undefined)) { if (!(s[i] === undefined)) {
srvString = srvString + s[i]; srvString = srvString + s[i];
} }
@ -164,15 +165,15 @@ function services(srv, callback) {
} }
} }
} }
if ((_darwin) && srvString === '*') { // service enumeration mnot yet suported on mac OS if ((_darwin) && srvString === '*') { // service enumeration not yet suported on mac OS
if (callback) { callback(result); } if (callback) { callback(result); }
resolve(result); resolve(result);
} }
let comm = (_darwin) ? 'ps -caxo pcpu,pmem,pid,command' : 'ps -axo pcpu,pmem,pid,command'; let args = (_darwin) ? ['-caxo', 'pcpu,pmem,pid,command'] : ['-axo', 'pcpu,pmem,pid,command'];
if (srvString !== '' && srvs.length > 0) { if (srvString !== '' && srvs.length > 0) {
exec(comm + ' | grep -v grep | grep -iE "' + srvString + '"', { maxBuffer: 1024 * 20000 }, function (error, stdout) { // lgtm [js/shell-command-constructed-from-input] util.execSave('ps', args).then((stdout) => {
if (!error) { if (stdout) {
let lines = stdout.toString().replace(/ +/g, ' ').replace(/,+/g, '.').split('\n'); let lines = stdout.replace(/ +/g, ' ').replace(/,+/g, '.').split('\n');
srvs.forEach(function (srv) { srvs.forEach(function (srv) {
let ps; let ps;
if (_darwin) { if (_darwin) {
@ -267,9 +268,10 @@ function services(srv, callback) {
resolve(result); resolve(result);
} }
} else { } else {
exec('ps -o comm | grep -v grep | egrep "' + srvString + '"', { maxBuffer: 1024 * 20000 }, function (error, stdout) { // lgtm [js/shell-command-constructed-from-input] args = ['-o', 'comm'];
if (!error) { util.execSave('ps', args).then((stdout) => {
let lines = stdout.toString().replace(/ +/g, ' ').replace(/,+/g, '.').split('\n'); if (stdout) {
let lines = stdout.replace(/ +/g, ' ').replace(/,+/g, '.').split('\n');
srvs.forEach(function (srv) { srvs.forEach(function (srv) {
let ps = lines.filter(function (e) { let ps = lines.filter(function (e) {
return e.indexOf(srv) !== -1; return e.indexOf(srv) !== -1;
@ -909,7 +911,8 @@ function processLoad(proc, callback) {
processesString.__proto__.trim = util.stringTrim; processesString.__proto__.trim = util.stringTrim;
const s = util.sanitizeShellString(proc); const s = util.sanitizeShellString(proc);
for (let i = 0; i <= 2000; i++) { const mathMin = util.mathMin;
for (let i = 0; i <= mathMin(s.length, 2000); i++) {
if (!(s[i] === undefined)) { if (!(s[i] === undefined)) {
processesString = processesString + s[i]; processesString = processesString + s[i];
} }

View File

@ -58,6 +58,7 @@ const stringToString = new String().toString;
const stringSubstr = new String().substr; const stringSubstr = new String().substr;
const stringTrim = new String().trim; const stringTrim = new String().trim;
const stringStartWith = new String().startsWith; const stringStartWith = new String().startsWith;
const mathMin = Math.min;
function isFunction(functionToCheck) { function isFunction(functionToCheck) {
let getType = {}; let getType = {};
@ -389,6 +390,42 @@ function powerShell(cmd) {
}); });
} }
function execSave(cmd, args, options) {
let result = '';
options = options || {};
return new Promise((resolve) => {
process.nextTick(() => {
try {
const child = spawn(cmd, args, options);
if (child && !child.pid) {
child.on('error', function () {
resolve(result);
});
}
if (child && child.pid) {
child.stdout.on('data', function (data) {
result += data.toString();
});
child.on('close', function () {
child.kill();
resolve(result);
});
child.on('error', function () {
child.kill();
resolve(result);
});
} else {
resolve(result);
}
} catch (e) {
resolve(result);
}
});
});
}
function getCodepage() { function getCodepage() {
if (_windows) { if (_windows) {
if (!codepage) { if (!codepage) {
@ -506,7 +543,7 @@ function countLines(lines, startingWith) {
function sanitizeShellString(str, strict = false) { function sanitizeShellString(str, strict = false) {
const s = str || ''; const s = str || '';
let result = ''; let result = '';
for (let i = 0; i <= 2000; i++) { for (let i = 0; i <= mathMin(s.length, 2000); i++) {
if (!(s[i] === undefined || if (!(s[i] === undefined ||
s[i] === '>' || s[i] === '>' ||
s[i] === '<' || s[i] === '<' ||
@ -925,6 +962,7 @@ exports.wmic = wmic;
exports.darwinXcodeExists = darwinXcodeExists; exports.darwinXcodeExists = darwinXcodeExists;
exports.getVboxmanage = getVboxmanage; exports.getVboxmanage = getVboxmanage;
exports.powerShell = powerShell; exports.powerShell = powerShell;
exports.execSave = execSave;
exports.nanoSeconds = nanoSeconds; exports.nanoSeconds = nanoSeconds;
exports.countUniqueLines = countUniqueLines; exports.countUniqueLines = countUniqueLines;
exports.countLines = countLines; exports.countLines = countLines;
@ -943,5 +981,6 @@ exports.stringToString = stringToString;
exports.stringSubstr = stringSubstr; exports.stringSubstr = stringSubstr;
exports.stringTrim = stringTrim; exports.stringTrim = stringTrim;
exports.stringStartWith = stringStartWith; exports.stringStartWith = stringStartWith;
exports.mathMin = mathMin;
exports.WINDIR = WINDIR; exports.WINDIR = WINDIR;
exports.getFilesInPath = getFilesInPath; exports.getFilesInPath = getFilesInPath;