Back to skill

Security audit

Free Ride 1.0.5

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-built for OpenRouter free-model management, but it can persistently change OpenClaw model configuration and run automatic rotation without strong safeguards.

Install only if you are comfortable letting this skill change your OpenClaw default model and fallback list. Back up ~/.openclaw/openclaw.json first, avoid running the watcher daemon unless you want automatic model rotation, and prefer pinned installer/dependency versions where possible.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
main.py:192
Finding
Malformed OpenClaw Configuration Can Be Silently Overwritten<![CDATA[ ## Vulnerability Details **File Location**: `main.py:192-207` **Vulnerability Type**: Unsafe error handling and destructive configuration overwrite **Risk Level**: Medium ### Vulnerable Code ```python def load_openclaw_config() -> dict: """Load OpenClaw configuration.""" if not OPENCLAW_CONFIG_PATH.exists(): return {} try: return json.loads(OPENCLAW_CONFIG_PATH.read_text()) except json.JSONDecodeError: return {} def save_openclaw_config(config: dict): """Save OpenClaw configuration.""" OPENCLAW_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True) OPENCLAW_CONFIG_PATH.write_text(json.dumps(config, indent=2)) ``` ### Technical Analysis When `~/.openclaw/openclaw.json` contains malformed or partially written JSON, `load_openclaw_config()` silently converts the parsing failure into an empty dictionary. Mutating commands then call `ensure_config_structure()` and reconstruct only the configuration fields needed by FreeRide. The resulting minimal configuration is written directly over the original file. The implementation does not: - Distinguish a nonexistent configuration from a malformed configuration. - Abort configuration changes after a parsing failure. - Create a backup of the original file. - Validate the complete resulting OpenClaw configuration. - Use an atomic temporary-file replacement. This behavior conflicts with the documented claim that unrelated gateway, channel, plugin, environment, custom-instruction, and named-agent settings are preserved. ### Attack Path 1. `~/.openclaw/openclaw.json` becomes invalid JSON. This could result from an interrupted write, manual editing error, filesystem issue, or modification by another local process. 2. The user invokes a mutating operation such as: - `freeride auto` - `freeride switch` - `freeride fallbacks` - A watcher operation that rotates the active model 3. `load_openclaw_config()` catches the parsing error and returns `{}`. ...[truncated 998 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Fail closed when an existing configuration cannot be parsed: ```python def load_openclaw_config() -> dict: if not OPENCLAW_CONFIG_PATH.exists(): return {} try: return json.loads(OPENCLAW_CONFIG_PATH.read_text()) except json.JSONDecodeError as exc: raise RuntimeError( f"Refusing to modify malformed configuration: " f"{OPENCLAW_CONFIG_PATH}" ) from exc ``` 2. Do not invoke any save operation after a load or validation failure. 3. Create a backup before every mutation, using restrictive permissions and a predictable retention policy. 4. Write changes atomically: - Create a temporary file in the same directory. - Set permissions to owner-only where appropriate. - Flush and synchronize the file. - Replace the destination with `os.replace()`. 5. Validate the resulting JSON structure before replacing the active file. 6. Preserve the original file permissions rather than relying on process defaults. 7. Report parsing failures clearly and require the user to repair or explicitly restore the configuration before FreeRide proceeds. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Mutable and Unpinned Installation Dependencies Create Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Locations**: - `requirements.txt:1` - `setup.py:10-12` - `README.md:50-52` - `skill.json:40` **Vulnerability Type**: Unpinned executable dependencies and mutable installation sources **Risk Level**: Low ### Vulnerable Code `requirements.txt:1`: ```text requests>=2.31.0 ``` `setup.py:10-12`: ```python install_requires=[ "requests>=2.31.0", ], ``` `README.md:50-52`: ```bash npx clawhub@latest install free-ride cd ~/.openclaw/workspace/skills/free-ride pip install -e . ``` `skill.json:40`: ```json "install": "npx clawhub@latest install freeride && cd ~/.openclaw/workspace/skills/free-ride && pip install -e ." ``` ### Technical Analysis The documented installation process executes `npx clawhub@latest`, meaning the installed ClawHub client is selected at installation time rather than being tied to a reviewed version. Its effective installation behavior may therefore change after this Skill has been audited. The Python dependency declaration accepts any future `requests` release at or above version 2.31.0. It provides no exact version, upper bound, lockfile, or package-integrity hash. Consequently, separate installations can resolve to different code. No evidence shows that the currently declared `requests` package is malicious. The issue is that the installation is not reproducible and trusts future upstream releases that were not part of this audit. ### Attack Path 1. A mutable upstream package or release is compromised, maliciously modified, or publishes an incompatible version. 2. A user follows the documented installation command. 3. `npx` retrieves and executes the then-current `clawhub` package because `@latest` is used. 4. `pip install -e .` resolves `requests>=2.31.0` to the currently available compatible release rather than a reviewed version. 5. Installation hooks or package code execute with the privileges of the user performing installation. 6. A compromised dependency could access files, env ...[truncated 817 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace `@latest` with a specifically reviewed ClawHub CLI version: ```bash npx clawhub@<reviewed-version> install free-ride ``` 2. Pin Python dependencies to reviewed versions rather than using only a lower bound: ```text requests==<reviewed-version> ``` 3. Generate and distribute a lockfile containing cryptographic hashes, and install with hash verification where supported. 4. Review transitive dependencies, not only the direct `requests` dependency. 5. Use a dedicated virtual environment instead of installing into a shared Python environment. 6. Document the trusted package indexes and avoid fallback to untrusted or unintended indexes. 7. Add automated dependency scanning and controlled update procedures. Version updates should be reviewed and tested before changing the lockfile. 8. Keep dependency constraints consistent across `requirements.txt`, `setup.py`, and Skill metadata. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (20)

Tainted flow: 'headers' from os.environ.get (line 68, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
}

    try:
        response = requests.get(OPENROUTER_API_URL, headers=headers, timeout=30)
        response.raise_for_status()
        data = response.json()
        return data.get("data", [])
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

External Transmission

Medium
Category
Data Exfiltration
Content
### Stop paying for AI. Start riding free.

[![ClawHub Downloads](https://api.clawhub-badge.xyz/badge/free-ride/downloads.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Current Installs](https://api.clawhub-badge.xyz/badge/free-ride/installs-current.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Stars](https://api.clawhub-badge.xyz/badge/free-ride/stars.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Version](https://api.clawhub-badge.xyz/badge/free-ride/version.svg)](https://clawhub.ai/skills/free-ride)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Stop paying for AI. Start riding free.

[![ClawHub Downloads](https://api.clawhub-badge.xyz/badge/free-ride/downloads.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Current Installs](https://api.clawhub-badge.xyz/badge/free-ride/installs-current.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Stars](https://api.clawhub-badge.xyz/badge/free-ride/stars.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Version](https://api.clawhub-badge.xyz/badge/free-ride/version.svg)](https://clawhub.ai/skills/free-ride)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Stop paying for AI. Start riding free.

[![ClawHub Downloads](https://api.clawhub-badge.xyz/badge/free-ride/downloads.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Current Installs](https://api.clawhub-badge.xyz/badge/free-ride/installs-current.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Stars](https://api.clawhub-badge.xyz/badge/free-ride/stars.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Version](https://api.clawhub-badge.xyz/badge/free-ride/version.svg)](https://clawhub.ai/skills/free-ride)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Stop paying for AI. Start riding free.

[![ClawHub Downloads](https://api.clawhub-badge.xyz/badge/free-ride/downloads.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Current Installs](https://api.clawhub-badge.xyz/badge/free-ride/installs-current.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Stars](https://api.clawhub-badge.xyz/badge/free-ride/stars.svg)](https://clawhub.ai/skills/free-ride)
[![ClawHub Version](https://api.clawhub-badge.xyz/badge/free-ride/version.svg)](https://clawhub.ai/skills/free-ride)
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The README clearly states that the tool automatically selects models, configures fallbacks, and preserves parts of the OpenClaw config, but it does not prominently warn that it will modify `openclaw.json`. Silent or under-emphasized configuration changes can surprise users and lead to unsafe assumptions about agent behavior, routing, or cost/privacy settings.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
The README instructs users to run `npx clawhub@latest install free-ride`, which fetches and executes the latest published package version at install time rather than a pinned, reviewed release. This creates a supply-chain risk: if the package or its dependency resolution is compromised, users may execute attacker-controlled code during installation.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The watcher daemon is presented as a convenience feature, but the documentation does not prominently warn that it continuously runs in the background, monitors for rate limits, and automatically rotates models. Background autonomous changes can affect system behavior, observability, and trust boundaries, especially in an agent environment where model changes may alter output quality or data handling.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill instructs use of environment access, filesystem reads/writes, and network-dependent operations, but it does not declare any explicit tool scope or permission boundary. That makes the skill harder to safely govern and review, and can lead to over-broad execution in environments where skills are expected to declare sensitive capabilities up front.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The invocation description is broad enough to match common user requests like reducing AI costs, model switching, or rate limits, which raises the chance the skill is triggered when the user did not intend configuration changes. In this skill's context, unintended activation is more dangerous because the prescribed workflow modifies local config and can restart a gateway service.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill directs the agent to run commands that modify ~/.openclaw/openclaw.json and restart the OpenClaw gateway without first requiring an explicit warning or confirmation from the user. This can disrupt active sessions, alter model routing, and create unexpected local state changes, especially if the skill is invoked automatically or under ambiguous user intent.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code path persists changes to the user's OpenClaw configuration file, which can alter active primary and fallback models. Although surrounding prints describe what is happening, there is no explicit confirmation step before committing the write, and this is a safety-relevant modification of user configuration data.

Rp1

Medium
Category
MCP Rug Pull
Confidence
97% confidence
Finding
The install command invokes `npx clawhub@latest`, which pulls and executes the newest published package version at install time rather than a reviewed, fixed version. This creates a supply-chain execution risk: if the upstream package is compromised or a breaking/malicious release is published, arbitrary code could run during skill installation. The risk is increased because this skill is explicitly designed to modify local OpenClaw configuration and is installed via a shell command users are likely to copy-paste.

External Transmission

Medium
Category
Data Exfiltration
Content
}

    try:
        response = requests.post(
            OPENROUTER_CHAT_URL,
            headers=headers,
            json=payload,
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code writes updated model configuration to the user's OpenClaw config as part of automatic rotation. Although there are console prints about rotation, there is no confirmation prompt before changing user configuration, and the daemon/auto-rotate behavior can modify persistent settings without an explicit warning in this file beyond the high-level description.

Missing User Warnings

Low
Confidence
78% confidence
Finding
The skill writes fetched model metadata to a cache file in the user's home directory. While this may be benign, the write occurs silently in the helper function with no local user-facing disclosure, comment, or prompt indicating that persistent cache data is being created or updated.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
Confidence
95% confidence
Finding
The dependency is specified as `requests>=2.31.0`, which permits installation of many future versions and does not guarantee a tested, reproducible, or known-safe release. In a security-sensitive agent skill that may make network requests to model APIs, this increases supply-chain and stability risk because a vulnerable or incompatible version could be resolved at install time.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding
Because `requests` is not pinned, it is impossible to verify whether the installed version includes fixes for known advisories affecting some releases. Given this skill's purpose involves OpenRouter/model management and likely outbound HTTP calls, an unsafe resolved version could expose credentials, request integrity, or other network-handling behavior.

Missing User Warnings

Low
Confidence
85% confidence
Finding
This manifest requires the user to provide an OPENROUTER_API_KEY via environment configuration, but the surrounding description only explains where to obtain the key and does not warn that the skill uses sensitive credentials. For manifest files, SQP-2 applies, and the file lacks any disclosure about privacy or credential-handling implications.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The skill persists operational state, including rate-limited model history and rotation metadata, to a hidden file in the user's home directory. While not inherently unsafe, this is a file write affecting user data and there is no explicit disclosure here that local state will be stored persistently.

Static analysis

No suspicious patterns detected.