T09 · Insecure Skill Coding Practices
Error
- Location
- agent.js:83
- Finding
- OS Command Injection Through an Unsafely Constructed Shell Command## Vulnerability Details **File Location**: `agent.js`, lines 83–90 **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```js // Prepare prompt const prompt = this.formatPrompt(question, category); // Execute consultation const result = execSync( `node scripts/auto_chatgpt.js "${prompt}"`, { encoding: 'utf8', timeout: 30000 } ); ``` ### Technical Analysis The `question` value originates from command-line arguments: ```js const question = process.argv.slice(2).join(' '); ``` It is passed to `formatPrompt()`, which embeds it into a prompt without escaping or validation. The resulting `prompt` is then interpolated directly into a command string passed to `child_process.execSync()`. `execSync()` executes command strings through a shell. Wrapping the value in double quotes does not make it safe because an attacker can supply a double quote to terminate the quoted argument and then append shell metacharacters and commands. Consultation-trigger checks do not sanitize the input or prevent shell syntax. ### Attack Path 1. An attacker supplies a command-line question containing a recognized consultation trigger and a shell payload. A conceptual input is: ```text 咨询chatgpt"; <attacker-command>; # ``` 2. `process.argv.slice(2).join(' ')` stores the complete attacker-controlled value in `question`. 3. `shouldConsultGPT()` recognizes the consultation phrase and allows execution to continue. 4. `formatPrompt()` incorporates the malicious question into `prompt` unchanged. 5. The interpolation in `execSync()` places the payload inside a shell command. 6. The injected double quote closes the intended argument, shell metacharacters introduce another command, and the trailing comment marker can suppress the remaining generated text. 7. The shell executes the attacker-supplied command with the privileges of the Node.js Agent process. Exploitation requires the code to reach `consultChatGPT()` and its expected externa ...[truncated 949 chars]
- Remediation
- ## Remediation Suggestions Do not construct a shell command by concatenating or interpolating user-controlled data. Invoke the executable with a separate argument array and disable shell processing. For example: ```js const { execFileSync } = require('child_process'); const path = require('path'); const scriptPath = path.join(__dirname, 'scripts', 'auto_chatgpt.js'); const result = execFileSync( process.execPath, [scriptPath, prompt], { encoding: 'utf8', timeout: 30000, shell: false } ); ``` Additional hardening measures should include: 1. Resolve the script from a trusted absolute path rather than relying on the current working directory. 2. Apply reasonable input and prompt length limits to reduce resource-exhaustion risks. 3. Validate that the prompt contains expected text data, while treating validation only as defense in depth rather than a replacement for argument-array execution. 4. Run the Agent under a dedicated, least-privileged operating-system account. 5. Restrict access to sensitive files, credentials, and browser profiles not required by the task. 6. Add automated tests containing quotes, command substitutions, pipes, semicolons, redirections, and newline characters to verify that all input is passed as one literal argument. 7. Avoid attempts to fix this issue solely with manual shell escaping, because escaping behavior differs across shells and operating systems.
