T09 · Insecure Skill Coding Practices
- Location
test_daytona.py:19- Finding
OpenRouter API Key Uploaded in Plaintext to a Third-Party Sandbox
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is coherent and mostly does what it advertises: it fetches a public model leaderboard and updates OpenClaw model defaults, with optional test scripts that require care around API keys.
Install only if you are comfortable with a skill that fetches public benchmark data and persistently changes OpenClaw's default primary and fallback models. Run the list command first if you want to inspect choices before changing config. Avoid running the Daytona E2E tests with a normal long-lived OpenRouter key; use a scoped disposable test key and pin CLI/package versions when reproducing the documented workflows.
test_daytona.py:19OpenRouter API Key Uploaded in Plaintext to a Third-Party Sandbox
test_clawhub.py:69Mutable and Unpinned Third-Party Packages Are Downloaded and Executed
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
The leaderboard has no models matching :free + is_benchmarked == true.
Check the live data:
curl -s "https://sequrity-ai.github.io/benchmarked-free-ride-ci/api/leaderboard.json" | python3 -c "
import sys, json
d = json.load(sys.stdin)
free = [m for m in d['leaderboard'] if ':free' in m.get('model_id','') and m.get('is_benchmarked')]
The description frames the skill as selecting or recommending models, but the content explicitly supports automatic reconfiguration of OpenClaw defaults and fallbacks. This mismatch is dangerous because it can mislead users and orchestrators into granting trust to what appears to be an advisory skill, when it actually performs persistent local changes and network access.
The description frames the skill as selecting or recommending models, but the content explicitly supports automatic reconfiguration of OpenClaw defaults and fallbacks. This mismatch is dangerous because it can mislead users and orchestrators into granting trust to what appears to be an advisory skill, when it actually performs persistent local changes and network access.
The description frames the skill as selecting or recommending models, but the content explicitly supports automatic reconfiguration of OpenClaw defaults and fallbacks. This mismatch is dangerous because it can mislead users and orchestrators into granting trust to what appears to be an advisory skill, when it actually performs persistent local changes and network access.
This file creates a Daytona sandbox, installs system packages with apt, installs npm packages globally, and installs the skill into the remote environment. A skill whose stated purpose is to recommend benchmarked free models does not inherently require remote environment provisioning or package installation; that is a separate orchestration capability.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
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.
Config directory not writable. Ensure ~/.openclaw/ exists:
mkdir -p ~/.openclaw
The skill declares network and file-write behavior in metadata but does not define an explicit tool/permission scope such as allowed-tools or permissions. That creates an authorization ambiguity: a user may expect a recommendation-only skill, while the implementation can fetch remote data and persistently modify local configuration, increasing the chance of overbroad execution in an agent environment.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
> - **default** — best overall task accuracy (composite score)
> - **--secure** — most resistant to prompt injection attacks"
If the user's request implies a preference (e.g. "safest", "most secure", "best overall"), infer the mode without asking.
## Data Source
The skill reads and writes persistent state in ~/.openclaw/openclaw.json, causing model selection changes to survive beyond the current invocation. In this context, persistence matters because remotely sourced model IDs can influence future agent runs, creating a durable configuration-manipulation risk if the remote data source is wrong, compromised, or unexpected.
with_score.sort(key=lambda m: m["cracker_security_rate"], reverse=True)
return with_score + without_score
# ── Config read/write ─────────────────────────────────────────────────────
def _read_config(self) -> dict:
"""Read current OpenClaw config."""
The skill does more than recommend models: it directly rewrites the user's persistent OpenClaw configuration file based on remotely fetched leaderboard data. This creates a trust-boundary issue because running a seemingly advisory skill can silently change future agent behavior and persist those changes across sessions.
The installation step uses npx clawhub@latest install benchmarked-free-ride, which pulls and executes the latest published package version at install time rather than a pinned, reviewed version. This creates a supply-chain risk: if the package is compromised, typosquatted, or a malicious update is published, arbitrary code could run on the user's machine during installation.
The manifest describes a skill for choosing free OpenRouter models from live benchmark results, but this file also reads Daytona and OpenRouter API credentials and, when available, provisions infrastructure and makes a live agent call through OpenRouter. Those capabilities are not necessary to justify the core purpose of ranking and recommending free models; they are auxiliary integration-test behaviors with broader external access.
The script executes npx clawhub@latest install ..., which pulls and runs the latest package version at test time without pinning or integrity verification. This creates a supply-chain risk: a compromised or malicious upstream release could execute arbitrary code inside the sandbox and influence the installed skill or test results.
Beyond ranking or listing models, this test invokes the skill's auto and switch flows and verifies that /root/.openclaw/openclaw.json is modified to set primary and fallback models. Automatically reconfiguring another tool's runtime model selection is a stronger capability than merely recommending performance-ranked free models, and the manifest description does not mention configuration mutation.
Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.
def upload_file(sandbox, local_path, remote_path):
"""Upload a local file into the sandbox."""
with open(local_path, "rb") as f:
sandbox.fs.upload_file(f.read(), remote_path)
print(f" uploaded {local_path} -> {remote_path}")
Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.
def upload_file(sandbox, local_path, remote_path):
"""Upload a local file into the sandbox."""
with open(local_path, "rb") as f:
sandbox.fs.upload_file(f.read(), remote_path)
print(f" uploaded {local_path} -> {remote_path}")
Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.
def upload_file(sandbox, local_path, remote_path):
"""Upload a local file into the sandbox."""
with open(local_path, "rb") as f:
sandbox.fs.upload_file(f.read(), remote_path)
print(f" uploaded {local_path} -> {remote_path}")
The script embeds OPENROUTER_API_KEY into a config file and uploads it into a remote Daytona sandbox. Even though this appears intended for end-to-end testing, the credential is transferred into another execution environment without any explicit user confirmation, minimization, or lifecycle controls shown here. If the sandbox is compromised, misconfigured, retained longer than expected, or its filesystem/logs are accessible, the API key could be exposed and abused.
This upload sends a generated openclaw configuration containing OPENROUTER_API_KEY into the sandbox filesystem. Unlike the other upload cases, this one transfers a real secret to remote storage, creating risk of credential exposure through sandbox compromise, residual files, or platform-side access.
}
config_json = json.dumps(openclaw_config, indent=2)
sandbox.fs.upload_file(config_json.encode("utf-8"), "/root/.openclaw/openclaw.json")
print(f" wrote openclaw.json with OpenRouter provider + {len(all_model_ids)} models")
# Send a simple prompt through openclaw
This code performs a real outbound API call from the sandbox through openclaw to OpenRouter. In a testing harness this may be expected, but it still causes external network activity and potential data disclosure without an explicit warning or consent gate at the point of use. If prompts or config contain sensitive data, that data may be sent to a third-party service.
The top-level docstring frames the skill as auto-configuring the best free AI models based on benchmarked quality scores and distinguishes that from proxy metrics. Yet the implementation includes a --secure mode and a dedicated security-based sorter using cracker_security_rate, which is a different selection criterion than the documented benchmark-score basis.
The stated purpose centers on using live benchmark CI results to recommend performance-ranked free models and explicitly excludes offline environments. However, commands such as status and config update helpers operate entirely on local configuration data and can be used independently of live recommendation output, broadening the skill beyond the narrowly described benchmark-selection role.
No suspicious patterns detected.