T09 · Insecure Skill Coding Practices
- Location
bridge/cli.py:246- Finding
Arbitrary Shell Command Execution Through the --execute Option
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This looks like a real Grok bridge skill, but it includes under-scoped local command execution and credential reuse behavior that should be reviewed before installation.
Install only if you are comfortable with selected files being sent to OpenRouter/Grok and with local generated-file writes. Avoid using the --execute option, prefer an explicit OPENROUTER_API_KEY or dedicated config key, review the installer dependency line before running it, and do not rely on shared OpenClaw auth profiles unless that reuse is intentional.
bridge/cli.py:246Arbitrary Shell Command Execution Through the --execute Option
install.sh:53Unpinned Dependency Installation and Incorrect Shell Parsing of Version Constraint
bridge/grok_bridge.py:82Implicit Cross-Agent OpenRouter Credential Discovery and Reuse
This is a true tool-parameter abuse issue because the CLI accepts a raw --execute string and forwards it directly to subprocess.run(..., shell=True). In the context of an agent skill that can write files from model output, chaining generation plus execution creates a dangerous pathway to arbitrary code execution and host compromise.
# Execute command if requested
if args.execute:
print(f"\nExecuting: {args.execute}", file=sys.stderr)
exec_result = subprocess.run(
args.execute,
shell=True,
capture_output=True,
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.
--prompt <text> Task instruction (required)
--mode <mode> Task mode: refactor|analyze|code|reason|orchestrate (default: reason)
--files <path...> Files to include as context
--system <text> Override system prompt (required for orchestrate mode)
--tools <path> JSON file with OpenAI-format tool definitions
--timeout <secs> Timeout in seconds (default: 120)
--output <path> Output file (default: stdout)
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.
--prompt <text> Task instruction (required)
--mode <mode> Task mode: refactor|analyze|code|reason|orchestrate (default: reason)
--files <path...> Files to include as context
--system <text> Override system prompt (required for orchestrate mode)
--tools <path> JSON file with OpenAI-format tool definitions
--timeout <secs> Timeout in seconds (default: 120)
--output <path> Output file (default: stdout)
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.
--prompt <text> Task instruction (required)
--mode <mode> Task mode: refactor|analyze|code|reason|orchestrate (default: reason)
--files <path...> Files to include as context
--system <text> Override system prompt (required for orchestrate mode)
--tools <path> JSON file with OpenAI-format tool definitions
--timeout <secs> Timeout in seconds (default: 120)
--output <path> Output file (default: stdout)
The skill explicitly advertises direct file writing capabilities but does not warn users that invoking the skill may modify files on disk. In an agent context, silent write capability increases the risk of unintended code changes, overwrites, or persistence of generated content without clear user consent.
The documentation instructs users to persist an API key in ~/.config/grok-swarm/config.json, creating long-lived local credential storage. Persistent secrets increase exposure if the workstation is compromised, backups are shared, or the file is accidentally included in sync, logs, or source control.
export OPENROUTER_API_KEY=sk-or-v1-...
Or create `~/.config/grok-swarm/config.json`:
```bash
mkdir -p ~/.config/grok-swarm
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
mkdir -p ~/.config/grok-swarm
echo '{"api_key": "sk-or-v1-..."}' > ~/.config/grok-swarm/config.json
chmod 600 ~/.config/grok-swarm/config.json
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def check_morph_available():
"""Check if Morph LLM MCP is installed."""
try:
result = subprocess.run(
["claude", "mcp", "list"],
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# Execute via claude mcp
try:
result = subprocess.run(
["claude", "mcp", "call", "morphllm", "edit_file",
"--file", validated_path,
"--code", block["code"],
The code executes args.execute with shell=True, which allows arbitrary shell command execution. In a skill that already generates and applies LLM-produced content, this is especially dangerous because a user or downstream automation could pass untrusted or model-influenced commands and gain full code execution on the host.
# Execute command if requested
if args.execute:
print(f"\nExecuting: {args.execute}", file=sys.stderr)
exec_result = subprocess.run(
args.execute,
shell=True,
capture_output=True,
The code reads API credentials from environment variables and multiple local auth/config files, but there is no user-facing disclosure in the CLI help, printed logs, or surrounding comments that the skill will inspect sensitive credential locations. Because this is a code file and the operation accesses secrets, it should include an explicit warning or disclosure.
The bridge reads arbitrary local files, concatenates their contents, and appends them to the system prompt before sending them to a third-party remote API. That creates a real confidentiality risk because sensitive source code, secrets, tokens, or proprietary data may be exfiltrated off-host without any explicit consent gate, filtering, or warning beyond normal CLI usage.
The installer copies a plugin manifest and bridge files into persistent OpenClaw extension/skill directories under ~/.openclaw, causing code and configuration to survive beyond the install session. In the context of an agent skill, persistence is security-relevant because it registers functionality that may later be enabled and executed by the host platform, even though this script openly discloses that behavior.
# Install plugin
log "Installing OpenClaw plugin..."
PLUGIN_DIR="$OPENCLAW_HOME/extensions/grok-swarm"
mkdir -p "$PLUGIN_DIR"
if [ -f "$SCRIPT_DIR/openclaw.plugin.json" ]; then
cp "$SCRIPT_DIR/openclaw.plugin.json" "$PLUGIN_DIR/"
log "Plugin manifest installed"
This shell script creates directories and copies files into ~/.openclaw and ~/.config, and also creates a config.json file. Although it logs what it is doing, there is no confirmation prompt or explicit pre-action warning before these filesystem changes, which are safety-relevant install-time modifications to user data locations.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
mkdir -p "$CONFIG_DIR"
if [ ! -f "$CONFIG_DIR/config.json" ]; then
echo '{"api_key": ""}' > "$CONFIG_DIR/config.json"
chmod 600 "$CONFIG_DIR/config.json"
warn "Created $CONFIG_DIR/config.json — add your OpenRouter API key"
fi
The API key setup instructions tell users to store credentials in an environment variable or local config file without warning about secret handling risks. While common practice, omitting guidance on avoiding shell history exposure, securing file permissions, and not committing config files can lead to accidental credential disclosure.
The script can write the model output to a specified output file and, with --write-files, create multiple files on disk from annotated response blocks. Although filenames written are reported afterward, there is no prior warning in the help text or inline disclosure that enabling these options will create or overwrite local files.
The inline comment says 'CLI invocations bypass this wrapper via src/plugin/index.ts', yet the code in this file is explicitly a command-line wrapper that parses CLI arguments and passes them to the Python bridge. That is an active contradiction in the local documentation about how this wrapper is used, even though it is not a high-severity security issue.
Detected: suspicious.dangerous_exec