From 07daa05fb06f24f96297abaa30c2ace8bfd8b525 Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Sun, 14 Feb 2021 11:59:07 +0100 Subject: [PATCH] docker, processLoad fixed potential security issue --- lib/docker.js | 64 ++++++++++++++++++++++++++++++++++++------------ lib/internet.js | 4 +-- lib/network.js | 28 ++++++++++++++------- lib/processes.js | 9 ++++++- 4 files changed, 77 insertions(+), 28 deletions(-) diff --git a/lib/docker.js b/lib/docker.js index 24b56b2..2dd1e2a 100644 --- a/lib/docker.js +++ b/lib/docker.js @@ -109,6 +109,9 @@ function dockerContainers(all, callback) { callback = all; all = false; } + if (typeof all !== 'boolean' && all !== undefined) { + all = false; + } all = all || false; let result = []; @@ -185,16 +188,20 @@ function dockerContainers(all, callback) { // container inspect (for one container) function dockerContainerInspect(containerID, payload) { - containerID = containerID || ''; return new Promise((resolve) => { process.nextTick(() => { - if (containerID) { + containerID = containerID || ''; + if (typeof containerID !== 'string') { + resolve(); + } + const containerIdSanitized = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerID, true)).trim(); + if (containerIdSanitized) { if (!_docker_socket) { _docker_socket = new DockerSocket(); } - _docker_socket.getInspect(containerID.trim(), data => { + _docker_socket.getInspect(containerIdSanitized.trim(), data => { try { resolve({ id: payload.Id, @@ -325,19 +332,39 @@ function docker_calcBlockIO(blkio_stats) { function dockerContainerStats(containerIDs, callback) { let containerArray = []; - // fallback - if only callback is given - if (util.isFunction(containerIDs) && !callback) { - callback = containerIDs; - containerArray = ['*']; - } else { - containerIDs = containerIDs || '*'; - containerIDs = containerIDs.trim().toLowerCase().replace(/,+/g, '|'); - containerArray = containerIDs.split('|'); - } - return new Promise((resolve) => { process.nextTick(() => { + // fallback - if only callback is given + if (util.isFunction(containerIDs) && !callback) { + callback = containerIDs; + containerArray = ['*']; + } else { + containerIDs = containerIDs || '*'; + if (typeof containerIDs !== 'string') { + if (callback) { callback([]); } + return resolve([]); + } + let containerIDsSanitized = ''; + containerIDsSanitized.__proto__.toLowerCase = util.stringToLower; + containerIDsSanitized.__proto__.replace = util.stringReplace; + containerIDsSanitized.__proto__.trim = util.stringTrim; + + const s = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerIDs, true)).trim(); + for (let i = 0; i <= 2000; i++) { + if (!(s[i] === undefined)) { + s[i].__proto__.toLowerCase = util.stringToLower; + const sl = s[i].toLowerCase(); + if (sl && sl[0] && !sl[1]) { + containerIDsSanitized = containerIDsSanitized + sl[0]; + } + } + } + + containerIDsSanitized = containerIDsSanitized.trim().toLowerCase().replace(/,+/g, '|'); + containerArray = containerIDs.split('|'); + } + const result = []; const workload = []; @@ -444,17 +471,22 @@ exports.dockerContainerStats = dockerContainerStats; // container processes (for one container) function dockerContainerProcesses(containerID, callback) { - containerID = containerID || ''; let result = []; return new Promise((resolve) => { process.nextTick(() => { - if (containerID) { + containerID = containerID || ''; + if (typeof containerID !== 'string') { + resolve(result); + } + const containerIdSanitized = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerID, true)).trim(); + + if (containerIdSanitized) { if (!_docker_socket) { _docker_socket = new DockerSocket(); } - _docker_socket.getProcesses(containerID, data => { + _docker_socket.getProcesses(containerIdSanitized, data => { /** * @namespace * @property {Array} Titles diff --git a/lib/internet.js b/lib/internet.js index 21936b6..c71f80d 100644 --- a/lib/internet.js +++ b/lib/internet.js @@ -40,7 +40,7 @@ function inetChecksite(url, callback) { status: 404, ms: null }; - if (typeof url !== "string") { + if (typeof url !== 'string') { if (callback) { callback(result); } return resolve(result); } @@ -131,7 +131,7 @@ function inetLatency(host, callback) { return new Promise((resolve) => { process.nextTick(() => { - if (typeof host !== "string") { + if (typeof host !== 'string') { if (callback) { callback(null); } return resolve(null); } diff --git a/lib/network.js b/lib/network.js index 4e10af7..34cfa0a 100644 --- a/lib/network.js +++ b/lib/network.js @@ -973,19 +973,29 @@ function calcNetworkSpeed(iface, rx_bytes, tx_bytes, operstate, rx_dropped, rx_e function networkStats(ifaces, callback) { let ifacesArray = []; - // fallback - if only callback is given - if (util.isFunction(ifaces) && !callback) { - callback = ifaces; - ifacesArray = [getDefaultNetworkInterface()]; - } else { - ifaces = ifaces || getDefaultNetworkInterface(); - ifaces = ifaces.trim().toLowerCase().replace(/,+/g, '|'); - ifacesArray = ifaces.split('|'); - } return new Promise((resolve) => { process.nextTick(() => { + // fallback - if only callback is given + if (util.isFunction(ifaces) && !callback) { + callback = ifaces; + ifacesArray = [getDefaultNetworkInterface()]; + } else { + if (typeof ifaces !== 'string' && ifaces !== undefined) { + if (callback) { callback([]); } + return resolve([]); + } + ifaces = ifaces || getDefaultNetworkInterface(); + + ifaces.__proto__.toLowerCase = util.stringToLower; + ifaces.__proto__.replace = util.stringReplace; + ifaces.__proto__.trim = util.stringTrim; + + ifaces = ifaces.trim().toLowerCase().replace(/,+/g, '|'); + ifacesArray = ifaces.split('|'); + } + const result = []; const workload = []; diff --git a/lib/processes.js b/lib/processes.js index 772b932..83a90cc 100644 --- a/lib/processes.js +++ b/lib/processes.js @@ -99,7 +99,7 @@ function services(srv, callback) { return new Promise((resolve) => { process.nextTick(() => { - if (typeof srv !== "string") { + if (typeof srv !== 'string') { if (callback) { callback([]); } return resolve([]); } @@ -892,6 +892,13 @@ function processLoad(proc, callback) { return new Promise((resolve) => { process.nextTick(() => { + proc = proc || ''; + + if (typeof proc !== 'string') { + if (callback) { callback([]); } + return resolve([]); + } + let processesString = ''; processesString.__proto__.toLowerCase = util.stringToLower; processesString.__proto__.replace = util.stringReplace;