Back to skill

Security audit

Tsz

Security checks for vulnerabilities and agentic risk

Overview

This package should go to Review because it is published as a self-improvement skill but also contains unrelated tools that use API keys, contact external AI services, and change OpenClaw configuration.

Do not install this package as a self-improvement skill until the publisher splits or repackages it under one clear identity, removes unrelated FreeRide/Gemini/proposal content, and adds explicit consent, redaction, reviewable diffs, backups, and rollback for persistent memory and configuration changes.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T02 · Agent Memory Poisoning

Error
Location
SKILL.md:16
Finding
Untrusted conversation content can be promoted into persistent agent instructions<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:16-25`, `SKILL.md:243-279`, `SKILL.md:393-400`, `hooks/openclaw/handler.js:8-27`, `hooks/openclaw/handler.js:46-51` **Vulnerability Type**: Persistent agent memory poisoning **Risk Level**: High ### Vulnerable Code `SKILL.md:16-25`: ```markdown | User corrects you | Log to `.learnings/LEARNINGS.md` with category `correction` | | User wants missing feature | Log to `.learnings/FEATURE_REQUESTS.md` | | API/external tool fails | Log to `.learnings/ERRORS.md` with integration details | | Knowledge was outdated | Log to `.learnings/LEARNINGS.md` with category `knowledge_gap` | | Found better approach | Log to `.learnings/LEARNINGS.md` with category `best_practice` | | Similar to existing entry | Link with `**See Also**`, consider priority bump | | Broadly applicable learning | Promote to `CLAUDE.md`, `AGENTS.md`, and/or `.github/copilot-instructions.md` | | Workflow improvements | Promote to `AGENTS.md` (OpenClaw workspace) | | Tool gotchas | Promote to `TOOLS.md` (OpenClaw workspace) | | Behavioral patterns | Promote to `SOUL.md` (OpenClaw workspace) | ``` `SKILL.md:393-400`: ```markdown ## Best Practices 1. **Log immediately** - context is freshest right after the issue 2. **Be specific** - future agents need to understand quickly 3. **Include reproduction steps** - especially for errors 4. **Link related files** - makes fixes easier 5. **Suggest concrete fixes** - not just "investigate" 6. **Use consistent categories** - enables filtering 7. **Promote aggressively** - if in doubt, add to CLAUDE.md or .github/copilot-instructions.md 8. **Review regularly** - stale learnings lose value ``` `hooks/openclaw/handler.js:46-51`: ```javascript if (Array.isArray(event.context.bootstrapFiles)) { event.context.bootstrapFiles.push({ path: 'SELF_IMPROVEMENT_REMINDER.md', content: REMINDER_CONTENT, virtual: true, }); } ``` ### Technical Analysis The skill directs the agent to derive learni ...[truncated 2029 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the “promote aggressively” guidance. 2. Require explicit human approval before modifying persistent instruction files. 3. Present a reviewable diff showing the exact source and destination text. 4. Record provenance for every learning, including session, user, source file, and timestamp. 5. Treat user messages, command output, API responses, and repository documents as untrusted data. 6. Reject entries containing imperative agent instructions, requests to weaken safeguards, credential-handling rules, or commands unrelated to verified project facts. 7. Restrict automatic promotion to concise, factual, project-specific metadata. 8. Add allowlists for permitted destination files and sections. 9. Maintain backups and provide a rollback command for promoted entries. 10. Keep the bootstrap hook disabled by default and clearly display when persistent learning behavior is active. ]]>

other

Error
Location
_meta.json:2
Finding
Package metadata and executable contents identify different products<![CDATA[ ## Vulnerability Details **File Location**: `_meta.json:2-5`, `SKILL.md:1-8`, `skill.json:2-6`, `main.py:2-6` **Vulnerability Type**: Package identity and content-integrity mismatch **Risk Level**: High ### Vulnerable Code `_meta.json:2-5`: ```json "ownerId": "kn70cjr952qdec1nx70zs6wefn7ynq2t", "slug": "self-improving-agent", "version": "1.0.5", "publishedAt": 1770103244219 ``` `SKILL.md:1-8`: ```markdown --- name: self-improvement description: "Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks." --- # Self-Improvement Skill Log learnings and errors to markdown files for continuous improvement. ``` `skill.json:2-6`: ```json "name": "freeride", "displayName": "FreeRide - Free AI for OpenClaw", "version": "1.0.0", "description": "Unlimited free AI access for OpenClaw via OpenRouter's free models with automatic fallback switching", "author": "OpenClaw Community", ``` `main.py:2-6`: ```python """ FreeRide - Free AI for OpenClaw Automatically manage and switch between free AI models on OpenRouter for unlimited free AI access. """ ``` ### Technical Analysis Marketplace metadata and `SKILL.md` identify the artifact as `self-improving-agent`, while `skill.json`, `main.py`, `watcher.py`, and `README.md` identify it as the unrelated FreeRide product. The package also contains proposal-generation assets and a Gemini image-generation utility. This discrepancy prevents a user or reviewer from deriving a coherent capability and trust model from the published identity. Installation consent based on the self-improvement description does not reliably cover OpenRouter ...[truncated 1192 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Split self-improvement, FreeRide, proposal assets, and image generation into separate packages. 2. Make `_meta.json`, `SKILL.md`, `skill.json`, README documentation, executable entry points, version numbers, author information, and repository URLs identify the same product. 3. Remove all unrelated executables and assets from each published artifact. 4. Generate a release manifest containing hashes for every distributed file. 5. Add CI checks that reject releases when metadata names, versions, or declared capabilities disagree. 6. Require security review whenever a release adds network destinations, credential access, persistent hooks, or home-directory configuration writes. 7. Republish the corrected package under a single unambiguous identity. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/generate_image.py:75
Finding
Unrelated image utility can upload local images and prompts to Gemini<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_image.py:22-27`, `scripts/generate_image.py:37-58`, `scripts/generate_image.py:75-108` **Vulnerability Type**: Excessive capability and undisclosed external data transfer **Risk Level**: Medium ### Vulnerable Code `scripts/generate_image.py:22-27`: ```python def get_api_key(provided_key: str | None) -> str | None: """Get API key from argument first, then environment.""" if provided_key: return provided_key return os.environ.get("GEMINI_API_KEY") ``` `scripts/generate_image.py:75-108`: ```python client = genai.Client(api_key=api_key) output_path = Path(args.filename) output_path.parent.mkdir(parents=True, exist_ok=True) input_image = None output_resolution = args.resolution if args.input_image: try: input_image = PILImage.open(args.input_image) print(f"Loaded input image: {args.input_image}") if args.resolution == "1K": width, height = input_image.size max_dim = max(width, height) if max_dim >= 3000: output_resolution = "4K" elif max_dim >= 1500: output_resolution = "2K" else: output_resolution = "1K" print(f"Auto-detected resolution: {output_resolution} (from input {width}x{height})") except Exception as e: print(f"Error loading input image: {e}", file=sys.stderr) sys.exit(1) if input_image: contents = [input_image, args.prompt] print(f"Editing image with resolution {output_resolution}...") else: contents = args.prompt print(f"Generating image with resolution {output_resolution}...") ``` The resulting content is transmitted by: ```python response = client.models.generate_content( model="gemini-3-pro-image-preview", contents=contents, config=types.GenerateContentConfig( response_modalities=["TEXT", "IMAGE"], image_config=types.ImageConfig( im ...[truncated 1859 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the image utility from this package and distribute it as a separately declared skill. 2. Before transmission, display the resolved input path, destination service, model, and data types to be uploaded. 3. Require explicit interactive confirmation for image uploads unless a dedicated noninteractive consent flag is provided. 4. Restrict readable input paths to an approved workspace or user-configured allowlist. 5. Refuse symlinks and unexpected file types where appropriate. 6. Add file-size limits and validate image formats before upload. 7. Document Google’s role as the external data processor and the applicable retention/privacy implications. 8. Remove the `--api-key` option or warn that command-line secrets may appear in process listings and shell history. 9. Prefer environment variables or a protected credential store. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
main.py:203
Finding
OpenClaw configuration is overwritten without atomicity, locking, backup, or rollback<![CDATA[ ## Vulnerability Details **File Location**: `main.py:203-206`, `main.py:300-364`, `watcher.py:166-184`, `watcher.py:268-289` **Vulnerability Type**: Unsafe security-relevant configuration update **Risk Level**: Medium ### Vulnerable Code `main.py:203-206`: ```python 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)) ``` `watcher.py:166-184`: ```python formatted = format_model_for_openclaw(next_model) config["agents"]["defaults"]["model"]["primary"] = formatted models = get_free_models(api_key) fallbacks = [] for m in models: if m["id"] != next_model and not is_model_rate_limited(state, m["id"]): fallbacks.append(format_model_for_openclaw(m["id"])) if len(fallbacks) >= 5: break config["agents"]["defaults"]["model"]["fallbacks"] = fallbacks save_openclaw_config(config) state["rotation_count"] = state.get("rotation_count", 0) + 1 state["last_rotation"] = datetime.now().isoformat() state["last_rotation_reason"] = reason save_state(state) ``` `watcher.py:268-289`: ```python state = load_state() while running: try: cleanup_old_rate_limits(state) check_and_rotate(api_key, state) except Exception as e: print(f"Error during check: {e}") for _ in range(CHECK_INTERVAL_SECONDS): if not running: break time.sleep(1) ``` ### Technical Analysis `save_openclaw_config` writes directly to the central `~/.openclaw/openclaw.json` file. It does not use a temporary file and atomic rename, acquire a file lock, preserve a backup, validate the complete resulting schema, enforce restrictive permissions, or provide rollback. The daemon can perform checks every 60 seconds and call this function whenever it decides rotation is needed. Concurrent writes by OpenClaw, FreeRide commands, or multiple watcher instances ...[truncated 1440 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Acquire an interprocess lock before reading and writing the configuration. 2. Reload the configuration after obtaining the lock to avoid stale read-modify-write operations. 3. Validate the complete output against the supported OpenClaw schema. 4. Write to a temporary file in the same directory. 5. Flush and `fsync` the temporary file, then replace the target with an atomic rename. 6. Preserve restrictive file permissions and explicitly use owner-only access where credentials may be present. 7. Create a timestamped backup before each modification. 8. Provide automatic rollback if OpenClaw rejects the new configuration. 9. Limit modifications to documented model fields and verify that unrelated fields remain byte-for-byte or semantically unchanged. 10. Prevent multiple watcher instances from running simultaneously. 11. Require explicit consent before enabling continuous automatic model replacement. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Dependencies use mutable version ranges without integrity verification<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1`, `scripts/generate_image.py:2-7`, `README.md:35-39` **Vulnerability Type**: Unpinned and unhashed third-party dependencies **Risk Level**: Medium ### Vulnerable Code `requirements.txt:1`: ```text requests>=2.31.0 ``` `scripts/generate_image.py:2-7`: ```python # /// script # requires-python = ">=3.10" # dependencies = [ # "google-genai>=1.0.0", # "pillow>=10.0.0", # ] # /// ``` `README.md:35-39`: ```bash git clone https://github.com/Shaivpidadi/FreeRide.git cd FreeRide pip install -r requirements.txt ``` ### Technical Analysis The package specifies open-ended minimum versions rather than reviewed exact versions. It does not provide a lockfile or cryptographic hashes. Consequently, installation at different times may resolve to different package and transitive-dependency versions. The inline `uv` metadata for the image utility similarly permits future `google-genai` and Pillow releases. Running the script through `uv run` can resolve packages that did not exist when this artifact was reviewed. No evidence was found that the currently named dependencies are malicious, typosquatted, or fetched from a nonstandard registry. The confirmed issue is the absence of reproducible and integrity-verified dependency resolution. ### Attack Path 1. A user follows the documented installation command or runs the inline-dependency image script. 2. The package manager resolves the newest versions satisfying the `>=` constraints. 3. A future compromised, malicious, or incompatible release satisfies the constraints. 4. Package installation or import executes code from that unreviewed release under the user’s account. 5. The dependency receives the process’s filesystem, environment, and network access, including potentially available API-key environment variables. ### Impact Assessment A compromised dependency would execute with the same privileges as the installing or invoking user. Poten ...[truncated 230 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact reviewed version. 2. Generate and commit a lockfile covering transitive dependencies. 3. Require cryptographic hashes during installation, such as pip hash-checking mode. 4. Use a controlled package index or registry allowlist. 5. Run automated vulnerability and provenance scanning in CI. 6. Review dependency updates before merging rather than resolving arbitrary future releases at runtime. 7. Avoid inline runtime dependency resolution for distributed scripts. 8. Produce a software bill of materials and sign release artifacts. 9. Periodically update pins through a controlled, tested dependency-update process. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (47)

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.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The file content describes a FreeRide tool for model switching, API-key usage, and configuration changes, which is fundamentally inconsistent with the declared skill purpose of self-improvement via capturing learnings and corrections. In a skill ecosystem, this type of capability/identity mismatch is dangerous because it can conceal unrelated or unauthorized behavior behind trusted metadata, undermining user consent and review.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The documented ability to auto-configure model settings and fallbacks changes OpenClaw behavior in ways unrelated to a self-improvement skill’s stated purpose. Because the skill context does not justify configuration management, these instructions suggest hidden scope expansion or deceptive packaging, increasing the risk of unauthorized modifications to user environment and routing of future AI traffic.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This skill is framed as a passive learning/error log, but it also instructs use of helper scripts that create directories/files and scaffold new skills from learning entries. That is a real expansion from note-taking into code/content generation and filesystem modification, which can surprise operators and increase write-side risk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This skill is framed as a passive learning/error log, but it also instructs use of helper scripts that create directories/files and scaffold new skills from learning entries. That is a real expansion from note-taking into code/content generation and filesystem modification, which can surprise operators and increase write-side risk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This skill is framed as a passive learning/error log, but it also instructs use of helper scripts that create directories/files and scaffold new skills from learning entries. That is a real expansion from note-taking into code/content generation and filesystem modification, which can surprise operators and increase write-side risk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This skill is framed as a passive learning/error log, but it also instructs use of helper scripts that create directories/files and scaffold new skills from learning entries. That is a real expansion from note-taking into code/content generation and filesystem modification, which can surprise operators and increase write-side risk.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The skill reads OPENROUTER_API_KEY from environment/config and makes external requests to OpenRouter, which is unrelated to a self-improvement function. In the context of a mislabeled skill, credential access plus outbound networking materially increases risk because the skill gains the ability to use sensitive runtime secrets and communicate externally under a misleading trust boundary.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The code implements a full 'FreeRide' model-management CLI for OpenRouter/OpenClaw rather than a self-improvement skill that captures learnings and corrections. This mismatch is dangerous because a user or orchestrator invoking the skill under the trusted 'self-improvement' label could unknowingly run code that changes model selection behavior and system configuration outside the declared purpose.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The code rewrites ~/.openclaw/openclaw.json, alters primary/fallback models, and can add an OpenRouter auth profile, none of which aligns with self-improvement. In this context, unauthorized configuration mutation can redirect future agent behavior, persist changes across sessions, and effectively act as a stealthy capability hijack.

Agent Config Directory Access

High
Category
Agent Snooping
Content
### Option 2: User-Level Configuration

Add to `~/.claude/settings.json` for global activation:

```json
{
Confidence
95% confidence
Finding
Directing users to modify ~/.claude/settings.json establishes persistent behavior in the agent's configuration directory, affecting future sessions and potentially all projects. In the context of an auto-triggered command hook, this is more dangerous because it creates durable execution of local scripts with little ongoing visibility, increasing the impact of later script tampering or unintended behavior.

Exfiltration Commands

High
Category
Prompt Injection
Content
### sessions_send

Send message to another session:
```
sessions_send(sessionKey="session-id", message="Learning: API requires X-Custom-Header")
```
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
This script implements external image generation/editing with Gemini rather than anything related to capturing learnings, errors, or corrections for a self-improvement skill. That mismatch is dangerous because it expands the skill’s capabilities beyond its declared purpose, increasing the chance of hidden or unauthorized actions and making security review and user trust assumptions invalid.

Credential Access

High
Category
Privilege Escalation
Content
def get_api_key(provided_key: str | None) -> str | None:
    """Get API key from argument first, then environment."""
    if provided_key:
        return provided_key
    return os.environ.get("GEMINI_API_KEY")
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The code calls an external generative AI service to create or edit images, which is unrelated to the declared self-improvement purpose. In this context, unjustified external capability is risky because it can be used to exfiltrate prompts/data, incur costs, or perform actions the user and reviewer would not expect from the skill.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The file's documented purpose and implementation are unrelated to the declared self-improvement skill. Instead of capturing learnings or corrections, it implements a FreeRide/OpenRouter model-rotation watcher, indicating significant scope drift and granting operational capabilities not justified by the manifest. In a skill ecosystem, this mismatch is dangerous because users or reviewers may authorize the skill based on benign metadata while the code performs unrelated control-plane actions.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
This section performs active external health checks against OpenRouter and is designed to support automated daemon behavior, which is not justified for a self-improvement skill. Such background network activity expands the attack surface, can consume credentials, and can be used to probe or manipulate service usage without user awareness. The contextual mismatch makes this more suspicious and dangerous than the same code in a clearly labeled monitoring skill.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
This code changes OpenClaw agent model configuration, including primary and fallback models, giving the skill the ability to alter runtime behavior of other components. In the context of a self-improvement skill, that is an unjustified privilege escalation path: a skill expected to record learnings can instead reconfigure model selection and influence future agent outputs or costs. The context makes this substantially more dangerous because the declared purpose would not lead reviewers to expect control over agent configuration.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The README states that the tool automatically manages OpenRouter free models, implying network interaction with an external API that is unrelated to capturing learnings or corrections. In the context of a mislabeled self-improvement skill, unjustified external communications are suspicious because they can exfiltrate metadata, obtain control inputs, or route user activity through third-party services without informed consent.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
The README instructs users to execute `npx clawhub@latest install free-ride`, which pulls and runs the latest package version without pinning. This creates a supply-chain risk: a compromised or malicious upstream release could be executed automatically on user machines, and the mismatch between the declared self-improvement skill and the README’s actual behavior makes that risk more concerning.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
Requiring an OpenRouter API key is unrelated to the declared self-improvement purpose and expands trust boundaries by asking users to provision third-party credentials. In a mismatched skill, credential collection is especially risky because users may provide secrets under false assumptions about what the skill is supposed to do.

Lp3

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding
The skill describes filesystem, environment, and network-capable operations but does not declare any explicit tool scope or allowlist. In agent systems, missing scope boundaries increases the chance that a skill can be invoked with broader-than-necessary privileges, especially when it includes hooks and shell-command examples.

Session Persistence

Medium
Category
Rogue Agent
Content
└── FEATURE_REQUESTS.md
```

### Create Learning Files

```bash
mkdir -p ~/.openclaw/workspace/.learnings
Confidence
84% confidence
Finding
The skill directs creation of persistent files under a home-directory workspace, enabling retention of conversation-derived data across sessions. Persistent memory is not inherently malicious, but in this context it becomes risky because the same skill also encourages broad logging of corrections, errors, and user context without strong privacy controls.

Ssd 3

Medium
Confidence
94% confidence
Finding
The skill explicitly promotes inter-session communication and sharing of learnings across sessions, which can persist and redistribute user-provided details beyond the original interaction. Without minimization, consent, or redaction guidance, this creates a meaningful privacy and data-handling risk.

Ssd 3

Medium
Confidence
95% confidence
Finding
The learning-entry template asks for full context and detailed metadata, which can easily capture sensitive prompts, proprietary file paths, incident details, or personal information in persistent storage. Because the default pattern is to append to markdown logs, exposure can persist unnoticed and be reused later by other agents.

Static analysis

No suspicious patterns detected.