T09 · Insecure Skill Coding Practices
- Location
manage_models.py:202- Finding
Persistent Plaintext Retention of Sensitive Task Content and Error Data
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has a coherent cost-routing purpose, but its optional execution mode gives spawned agents broad file-writing authority and stores full task text locally without clear disclosure.
Install only if you specifically want model routing plus optional multi-agent execution. Avoid --execute on sensitive tasks or in important workspaces unless you are comfortable with spawned agents writing files, retained session state, and local storage of task text/errors. Review and periodically delete ~/.openclaw/workspace/swarm_memory.json and swarm_insights.json, and treat smart_find.py as a broad local file-content disclosure utility.
manage_models.py:202Persistent Plaintext Retention of Sensitive Task Content and Error Data
manage_models.py:118Untrusted Task Text Is Delegated to File-Writing Agents Without Workspace Isolation
smart_find.py:13Undocumented Recursive File Finder Can Disclose Arbitrary Readable File Content
The README advertises plan ... --execute and describes spawning sub-agents, but it does not clearly warn that this mode will automatically launch multiple agents and may perform actions beyond passive planning. In an agentic tooling context, insufficient disclosure can lead users to trigger autonomous execution unintentionally, increasing the risk of unwanted commands, resource usage, or changes in the local environment.
The skill explicitly states it modifies the persistent user configuration file at ~/.openclaw/openclaw.json. Persistent configuration changes are security-relevant because they can outlive the current run, silently alter future model routing behavior, and potentially weaken trust boundaries or redirect later activity if the config is changed unsafely or without strong user consent.
This skill performs the following operations to enable dynamic model routing:
1. **Read/Write Configuration**: Modifies `~/.openclaw/openclaw.json` to update model fallbacks and enable new models dynamically. This is the core functionality.
2. **Network Access**: Connects to `https://openrouter.ai/api/v1/models` (HTTPS only) to fetch current pricing and model lists. No user data is sent.
3. **Process Execution**: Spawns sub-processes via `openclaw sessions spawn` to orchestrate multi-agent workflows (Planner/Executor/Reviewer).
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
# Create custom routing in ~/.openclaw/model-routing.json
{
"patterns": {
"translation": ["gemini-2.0-flash", "gpt-4o-mini"],
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"""
try:
# Explicitly use shell=False for security (default, but explicit is better)
result = subprocess.run(
cmd_list,
capture_output=True,
text=True,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
try:
# Try to call model-benchmarks skill
cmd = ["python3", "skills/model-benchmarks/scripts/run.py", "recommend", "--task", task_type, "--format", "json"]
result = subprocess.run(cmd, capture_output=True, text=True, cwd=os.path.expanduser("~/.openclaw/workspace"))
if result.returncode == 0:
data = json.loads(result.stdout)
The script automatically prints the full contents of the highest-scoring matched file based solely on a fuzzy query. In a local workspace, this can unintentionally expose secrets, credentials, private documents, or other sensitive data if the match is unexpected or manipulated by naming, especially because there is no confirmation, preview-only mode, or path restriction.
The document switches into a Chinese-language section beginning at L11, but it does not state whether language selection is optional or user-driven. This can create a natural-language policy issue if the skill assumes or prioritizes a specific language without explicit opt-in.
Line L74 states that the skill tracks success rates in swarm_memory.json, which means it persists operational data to disk. The README explains the feature but does not warn users that local state will be written and retained, which is relevant to user data and system integrity expectations.
This README states that the skill fetches current OpenRouter pricing and integrates with benchmark data sources, which implies outbound network requests. The markdown does not warn users that using these commands may contact external services and transmit task or system-related data, which is the kind of disclosure SQP-2 expects for markdown skill descriptions.
The docstring says the function will 'Generate OpenClaw config patch to enable a model,' which suggests activation behavior, while the module-level documentation states the script modifies the local OpenClaw configuration file. In reality, this function reads config state and emits a patch to stdout without writing the configuration file itself, creating a documentation-to-code mismatch about the actual side effect.
No suspicious patterns detected.