CVE-2024-21488 (published 2024-01-30T05:15Z)

Versions of the package network before 0.7.0 are vulnerable to Arbitrary Command Injection due to use of the child_process exec function without input sanitization. If (attacker-controlled) user input is given to the mac_address_for function of the package, it is possible for the attacker to execute arbitrary commands on the operating system that this package is being run on.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-77
cwe_name: Improper Neutralization of Special Elements used in a Command ('Command Injection')
description: The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.
extended_description: 
            Many protocols and products have their own custom command language. While OS or shell command strings are frequently discovered and targeted, developers may not realize that these other command languages might also be vulnerable to attacks.
         
         

Fix information:
repo_url: https://github.com/tomas/network
commit_details: repo_url: https://github.com/tomas/network
author: Tomás Pollak
author_date: 2024-01-23 22:32:25-03:00
msg: Remove unneeded require in win32
repository: repo_url: https://github.com/tomas/network
repo_name: tomas/network
description: The missing network utilities in Node.js. 
repo_language: JavaScript
owner: tomas
file_changes: filename: win32.js
change_type: ModificationType.MODIFY
diff: @@ -1,7 +1,6 @@
 "use strict";
 
 var wmic = require('wmic'),
-    exec = require('child_process').exec,
     os   = require('os');
 
 function get_wmic_ip_value(what, nic_name, cb){

programming_language: JavaScript
repo_url: https://github.com/tomas/network
commit_details: repo_url: https://github.com/tomas/network
author: Tomás Pollak
author_date: 2024-01-23 22:32:17-03:00
msg: Ensure valid nic in darwin too
repository: repo_url: https://github.com/tomas/network
repo_name: tomas/network
description: The missing network utilities in Node.js. 
repo_language: JavaScript
owner: tomas
file_changes: filename: darwin.js
change_type: ModificationType.MODIFY
diff: @@ -16,6 +16,10 @@ function trim_exec(cmd, cb) {
   })
 }
 
+function ensure_valid_nic(str) {
+  if (str.match(/[^\w]/))
+    throw new Error("Invalid nic name given: " + str);
+}
 
 function determine_nic_type(str) {
   return str.match(/Ethernet/)
@@ -62,20 +66,24 @@ exports.interface_type_for = function(nic_name, cb) {
 */
 
 exports.mac_address_for = function(nic_name, cb) {
+  ensure_valid_nic(nic_name);
   var cmd = "networksetup -getmacaddress " + nic_name + " | awk '{print $3}'";
   trim_exec(cmd, cb);
 };
 
 exports.gateway_ip_for = function(nic_name, cb) {
+  ensure_valid_nic(nic_name);
   var cmd = "ipconfig getoption " + nic_name + " router";
   trim_exec(cmd, cb);
 };
 
 exports.netmask_for = function(nic_name, cb) {
+  ensure_valid_nic(nic_name);
   var cmd = "ipconfig getoption " + nic_name + " subnet_mask";
   trim_exec(cmd, cb);
 };
-exports.status_for = function(nic_name, cb){
+exports.status_for = function(nic_name, cb) {
+  ensure_valid_nic(nic_name);
   var cmd = "netstat -rn | grep " + nic_name + ' | grep UG | wc -l | sed -e "s/1/active/" | sed -e "s/0/inactive/"'
   trim_exec(cmd, cb)
 }
@@ -140,8 +148,7 @@ exports.get_network_interfaces_list = function(cb) {
       append_data(obj);
     })
 
-    if (count == 0)
-      cb(new Error('No interfaces found.'))
+    if (count == 0) cb(new Error('No interfaces found.'))
   })
 
 };

programming_language: JavaScript
repo_url: https://github.com/tomas/network
commit_details: repo_url: https://github.com/tomas/network
author: Tomás Pollak
author_date: 2024-01-23 22:30:44-03:00
msg: Validate nic name under linux
repository: repo_url: https://github.com/tomas/network
repo_name: tomas/network
description: The missing network utilities in Node.js. 
repo_language: JavaScript
owner: tomas
file_changes: filename: linux.js
change_type: ModificationType.MODIFY
diff: @@ -13,12 +13,21 @@ function trim_exec(cmd, cb) {
   })
 }
 
+function ensure_valid_nic(str) {
+  if (str.match(/[^\w]/))
+    throw new Error("Invalid nic name given: " + str);
+}
+
 // If no wifi, then there is no error but cbed get's a null in second param.
 exports.get_active_network_interface_name = function(cb) {
   var cmd = "netstat -rn | grep UG | awk '{print $NF}'";
-  exec(cmd, function(err, stdout) {
+  exec(cmd, function(err, stdout, stderr) {
     if (err) return cb(err);
 
+    if (stderr.toString().match('not found')) {
+      return cb(new Error('Command failed: ' + stderr.toString().trim()))
+    }
+
     var raw = stdout.toString().trim().split('\n');
     if (raw.length === 0 || raw === [''])
       return cb(new Error('No active network interface found.'));
@@ -28,21 +37,25 @@ exports.get_active_network_interface_name = function(cb) {
 };
 
 exports.interface_type_for = function(nic_name, cb) {
+  ensure_valid_nic(nic_name);
   exec('cat /proc/net/wireless | grep ' + nic_name, function(err, out) {
     return cb(null, err ? 'Wired' : 'Wireless')
   })
 };
 
 exports.mac_address_for = function(nic_name, cb) {
+  ensure_valid_nic(nic_name);
   var cmd = 'cat /sys/class/net/' + nic_name + '/address';
   trim_exec(cmd, cb);
 };
 
 exports.gateway_ip_for = function(nic_name, cb) {
+  ensure_valid_nic(nic_name);
   trim_exec("ip r | grep " + nic_name + " | grep default | cut -d ' ' -f 3 | head -n1", cb);
 };
 
 exports.netmask_for = function(nic_name, cb) {
+  ensure_valid_nic(nic_name);
   var cmd = "ifconfig " + nic_name + " 2> /dev/null | egrep 'netmask|Mask:' | awk '{print $4}' | sed 's/Mask://'";
   trim_exec(cmd, cb);
 };

programming_language: JavaScript