T09 · Insecure Skill Coding Practices
- Location
scripts/apply_patch.py:75- Finding
Unauthenticated Patch File Can Modify Active Gateway Configuration
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This deprecated sync skill is not clearly malicious, but it should be reviewed because it can rewrite OpenClaw gateway configuration from weakly validated patch files, restart the gateway, and send operational details to a hardcoded Telegram chat.
Install only if you understand this is a deprecated operational skill and still need it. Before running it, restrict who can create or modify patch files, verify the exact patch contents and source, avoid broad .env sourcing where possible, confirm Telegram is an approved destination for operational details, and keep backups so OpenClaw configuration can be restored if the gateway fails after a patch.
scripts/apply_patch.py:75Unauthenticated Patch File Can Modify Active Gateway Configuration
The declared description says this skill syncs models from a live API and reports results, but the body also includes patch application, config replacement, gateway restart, and status polling. This mismatch can cause operators or orchestrators to trust the skill as low-risk synchronization logic when it actually performs privileged configuration changes and service-affecting actions.
The skill explicitly sources ~/.openclaw/.env, which exposes all environment variables in that file to the shell process and any subprocesses. Broadly loading credentials is risky because the called script or later commands may access or leak secrets beyond the single API key actually needed, and the skill has additional network and messaging behaviors that increase exfiltration risk.
source ~/.openclaw/.env && python3 ~/.openclaw/workspace/skills/kilocode-model-sync/scripts/sync_models.py
Parse the JSON result from stdout. It contains:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ── Config ────────────────────────────────────────────────────────────────────
API_URL = "https://api.kilo.ai/api/gateway/models"
ENV_FILE = Path.home() / ".openclaw" / ".env"
OPENCLAW_JSON = Path.home() / ".openclaw" / "openclaw.json"
DEFAULT_OUT = Path.home() / ".openclaw" / "workspace" / "kilocode-models"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# ── Config ────────────────────────────────────────────────────────────────────
API_URL = "https://api.kilo.ai/api/gateway/models"
ENV_FILE = Path.home() / ".openclaw" / ".env"
OPENCLAW_JSON = Path.home() / ".openclaw" / "openclaw.json"
DEFAULT_OUT = Path.home() / ".openclaw" / "workspace" / "kilocode-models"
The skill requests capabilities that include environment access, file reads/writes, network use, and shell execution, but it does not declare any explicit tool restrictions. In a skill that can edit configuration, source credentials from a .env file, message external parties, and restart infrastructure, the absence of scoped permissions increases the blast radius if the skill is invoked or modified unexpectedly.
The header states the skill is deprecated and should not be run, yet the remainder provides detailed execution instructions, including patching configuration and restarting a gateway. Contradictory guidance is dangerous because an agent or operator may still follow the actionable steps, defeating the warning and increasing the chance of unintended execution.
The skill instructs sending operational details, including model inventory changes and infrastructure state, to Telegram without an explicit privacy or approval warning. External messaging can leak internal configuration, deployment timing, model identifiers, backup paths, or failure details to a third-party channel not appropriate for sensitive operational data.
The skill writes a persistent memory note even when no changes occur. Persistent logging of operational activity is not always unsafe, but it can accumulate sensitive metadata such as dates, model counts, and execution history that may be unnecessary and could later aid reconnaissance.
status == "no_change"Write a brief memory note and stop. No notification needed.
# memory/YYYY-MM-DD.md entry:
The skill appends detailed mission-control entries containing added/removed/updated model IDs, backup paths, restart outcomes, and approval metadata to persistent memory. This creates a durable record of internal configuration changes and file locations that could expose sensitive operational context if the memory store is broadly accessible.
---
## Step 6 — Write mission control entry
Append to `~/.openclaw/workspace/memory/YYYY-MM-DD.md`:
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def restart_gateway(openclaw: str) -> dict:
"""Restart the OpenClaw gateway and wait for it to come back up."""
# Send restart
result = subprocess.run(
[openclaw, "gateway", "restart"],
capture_output=True, text=True, timeout=30
)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# Wait for gateway to come back (poll up to 30s)
for attempt in range(10):
time.sleep(3)
probe = subprocess.run(
[openclaw, "gateway", "status"],
capture_output=True, text=True, timeout=10
)
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
# 5. Mark patch as applied
patch["applied"] = True
patch["applied_at"] = datetime.now(timezone.utc).isoformat()
patch_path.write_text(json.dumps(patch, indent=2))
# 6. Restart gateway
try:
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
from urllib.error import URLError, HTTPError
# ── Config ────────────────────────────────────────────────────────────────────
API_URL = "https://api.kilo.ai/api/gateway/models"
ENV_FILE = Path.home() / ".openclaw" / ".env"
OPENCLAW_JSON = Path.home() / ".openclaw" / "openclaw.json"
DEFAULT_OUT = Path.home() / ".openclaw" / "workspace" / "kilocode-models"
This code loads KILOCODE_API_KEY from the environment or ~/.openclaw/.env and immediately uses it as a Bearer token in an outbound HTTP request. Although the module docstring describes fetching models, there is no explicit user-facing warning, prompt, or inline disclosure near the credential access and transmission.
The skill hardcodes Telegram as the communication mechanism and target, removing user choice over where operational data is sent. While not inherently malicious, forced external delivery increases the chance of policy violations or accidental disclosure when the environment expects internal-only communications.
The script creates and overwrites JSON artifacts under ~/.openclaw/workspace/kilocode-models, including the current day's snapshot and optional diff/patch files. While file output is part of the tool's purpose, the write operations themselves have no nearby confirmation or user-facing disclosure beyond the brief top-level usage text.
No suspicious patterns detected.