T09 · Insecure Skill Coding Practices
- Location
auto-add-commands.js:58- Finding
Unescaped CLI Output Is Embedded into Generated JavaScript Source
- Content
View full analysis
Vulnerability Details
File Location:
auto-add-commands.js:58-69, 100-104
Vulnerability Type: Unsafe source-code generation
Risk Level: HighVulnerable Code
javascript function generateCommandCode(cmd) { return ` { slug: '${cmd.slug}', command: '${cmd.command}', description: '${cmd.description}', safety: SAFETY.SAFE, source: SOURCE.NATIVE, category: 'OpenClaw', executeHint: '执行命令', execute: async () => { return \`提示:请使用 OpenClaw 直接执行 \\\`${cmd.command}\\\`\n\n(此命令为系统命令)\`; } },`; }javascript const code = commands.map(generateCommandCode).join('\n'); // 输出到文件 const outputPath = path.join(__dirname, 'openclaw-commands.generated.js'); fs.writeFileSync(outputPath, code, 'utf8');The values used by this function originate from the output of a local executable:
javascript const output = execSync('openclaw --help', { encoding: 'utf8' });Technical Analysis
The generator interpolates command names and descriptions obtained from
openclaw --helpdirectly into JavaScript string literals. It does not escape single quotes, backslashes, template-literal metacharacters, or JavaScript line terminators before generating the source file.Although the command-name parser restricts command names to a relatively narrow character set, the description is captured using
(.+)and subsequently inserted into:javascript description: '${cmd.description}',An attacker who controls which
openclawexecutable is resolved throughPATH, or who otherwise controls its help output, can include a single quote and JavaScript syntax in a command description. That syntax will be written intoopenclaw-commands.generated.js.The script does not import the generated file automatically. Its output explicitly instructs the operator to copy the generated code into
commands.js, so exploitation requires the generated source to be copied, imported, or otherwise ex ...[truncated 1409 chars]- Remediation
View remediation
Remediation Suggestions
- Do not generate executable JavaScript from command output. Store generated command metadata as JSON and load it as data.
- Serialize every externally derived value with
JSON.stringify()rather than manually placing it between quotes. - Enforce strict validation and length limits on descriptions, command names, categories, and other generated fields.
- Resolve
openclawto an expected absolute path and verify that the executable is trusted before running it. - Prefer
execFileSync()with an absolute executable path and an argument array:javascript execFileSync(trustedOpenClawPath, ['--help'], { encoding: 'utf8', shell: false }); - If JavaScript generation is unavoidable, generate object data using a trusted serializer rather than template interpolation:
javascript const serialized = JSON.stringify(commandMetadata, null, 2); - Remove the workflow that asks users to copy generated source manually. Use a validated data import path instead.
- Add tests containing quotes, backslashes, newlines, Unicode separators, and attempted JavaScript payloads to verify that all generated values remain inert data.
