By Julien Brouchier, MTS @ Trent AI
We ran a behavioral security analysis on 2,354 of the most popular skills on ClawHub. The results: 86% had security issues. But here's the thing: the overwhelming majority weren't malicious. They were built by developers who shipped good tools with preventable gaps.
The same six patterns showed up across the corpus with remarkable consistency. If you publish skills on ClawHub, or plan to, this is what to look for and how to fix it.
Pattern 1: Plaintext Credentials
The most common finding. API keys and tokens stored directly in configuration files, scripts, or SKILL.md.
What we saw
Skills that hardcode API keys in the main script or store them in a config file committed alongside the code. Anyone who reads the source has the key. The thinking is usually some version of: "I'll drop my key in here for testing. I'll swap it out before I publish." Then the publish step happens and the key ships.
Why it matters more for OpenClaw
In a traditional package, a leaked API key is bad. In OpenClaw, the agent actively uses that key. An attacker who compromises the skill has the key and an autonomous agent willing to use it.
The fix
# Instead of this:
API_KEY = "sk-abc123..."
# Do this:
import os
API_KEY = os.environ.get("MY_SERVICE_API_KEY")
if not API_KEY:
raise ValueError("MY_SERVICE_API_KEY not set")
Document in your SKILL.md that users need to set the environment variable. Never store credentials in any file that ships with the skill.
Pattern 2: Un-scoped API Access
Skills that request broad permissions when they only need a narrow slice.
What we saw
A skill that sends emails requesting full Gmail access instead of just gmail.send. A calendar tool requesting read/write to all calendars when it only needs one. Skills that request filesystem access to / when they only need ./data/.
Why it matters more for OpenClaw
Agents use the permissions they're given. If your skill requests broad access "just in case", you've expanded the blast radius of every vulnerability in your code. A prompt injection attack against a skill with full filesystem access is a completely different incident than one against a skill scoped to a single directory.
The fix
Request the minimum permissions your skill actually needs. If you need to read one file, request access to that file. Not the directory, not the filesystem. Audit your permission requests and ask: "If an attacker controlled the input to this skill, what could they reach?"
Pattern 3: Missing Input Validation
No sanitization of external or user-provided data. Injection vectors left wide open.
What we saw
File paths accepted without validation, meaning a prompt injection could point the skill at ~/.ssh/id_rsa or ~/.aws/credentials. URLs passed directly to HTTP libraries without checking the scheme or domain. User input concatenated into shell commands.
Why it matters more for OpenClaw
Traditional software gets input from users through forms and APIs. OpenClaw skills get input from agents, and agents can be manipulated through prompt injection. The input your skill receives isn't always what the user intended. If you don't validate it, you're trusting the agent's entire conversation context.
The web learned this the hard way in the late 1990s and early 2000s, when SQL injection and XSS taught a generation of developers that all input is untrusted, including input that looks like it came from your own UI. Agentic skills are at the same point right now. The input looks like it came from your user; in practice it came from a model that read whatever was in front of it.
The fix
import os
ALLOWED_DIR = os.path.abspath("./workspace")
def safe_read(filepath):
resolved = os.path.abspath(filepath)
if not resolved.startswith(ALLOWED_DIR):
raise ValueError(f"Path {filepath} outside allowed directory")
return open(resolved).read()
Validate every input. Allowlist over blocklist. Treat all input as untrusted, regardless of source.
Pattern 4: Unverified External Endpoints
Blind trust in third-party APIs and services.
What we saw
Skills that POST data to external endpoints without verifying the response. Skills that follow redirects without checking the destination. Skills that download and execute code from URLs embedded in configuration.
Why it matters more for OpenClaw
An agent doesn't question whether a URL is trustworthy. It follows instructions. If your skill sends data to an external API, and that API is compromised or spoofed, the agent will dutifully send whatever data it has access to. There's no human in the loop squinting at a suspicious redirect.
The fix
Pin the URLs your skill communicates with and verify TLS certificates. Check response status codes and content types before processing. Never follow redirects blindly. If your skill downloads anything, verify a checksum.
Pattern 5: Missing Sandboxing
No isolation between the skill and the host environment.
What we saw
Skills that run with full host access. Skills that share the agent's environment variables (including credentials for other services). Skills that can read and write to any directory the agent process can reach.
Why it matters more for OpenClaw
OpenClaw agents often have access to multiple tools and services. A skill without sandboxing boundaries can reach everything the agent can reach, not just the resources relevant to the skill's stated function. One compromised skill means every connected service is exposed.
The fix
Run skills in the most restrictive environment possible. If OpenClaw supports permission scoping for your use case, use it. Avoid sharing environment variables between skills. Each skill should only see the credentials it needs. Document what your skill accesses so users can make informed decisions.
Pattern 6: Auto-push Without Approval
Skills that write to git, send messages, or make API calls with no user confirmation step.
What we saw
Skills that commit and push to repositories automatically. Skills that send Slack messages, emails, or webhooks without asking. Skills that create or modify cloud resources without a confirmation prompt.
Why it matters more for OpenClaw
This is the pattern that turns a vulnerability into an incident. A skill with unvalidated input AND auto-push can be manipulated into committing malicious code, sending phishing messages, or modifying infrastructure, all without the user seeing it happen. The agent executes, the skill pushes, and nobody reviews the action.
The fix
Add a confirmation step for any destructive or externally-visible operation. At minimum, log what the skill is about to do and wait for explicit user approval. For git operations: stage the changes and present them before pushing. For API calls: show the payload before sending.
The Pattern Behind the Patterns
These six issues aren't random. They share a root cause: the OpenClaw ecosystem makes it easy to skip these controls and provides no feedback when you do.
There's no pre-publish check that flags plaintext credentials. No template that starts you off with input validation. No required permissions declaration in the skill spec. Developers build skills the way the ecosystem teaches them, and the ecosystem doesn't teach security.
It's also not obvious where the fix should live. Should it sit in the skill spec, in ClawHub's publish flow, in the host runtime, or in the LLM itself? Web security ran into the same question twenty years ago about input validation: client, business logic, framework, or language. It eventually got answered in layers, not in one place. Agentic skills are still at the question stage.
The 226 benign packages in our scan aren't benign because their developers are better (this is the pattern I keep coming back to). They're benign because their architecture mitigates risk: scoped permissions, validated inputs, explicit user confirmation. The code quality is often similar across all three categories. The architecture is what separates them.
What Separates Vulnerable From Malicious
We also found 103 genuinely malicious packages (4.4%). The diagnostic signal that separates them from vulnerable packages is not the number of findings. It's the density of CRITICAL findings:
| Category | Avg. findings | CRITICAL per package | Pattern |
|---|---|---|---|
| Malicious (103) | 9-10 | 4-6 | Credential harvesting, data exfiltration, prompt injection |
| Vulnerable (2,025) | 4-6 | 0-1 | Missing validation, plaintext creds, broad permissions |
| Benign (226) | 0-2 | Rare | Architecture mitigates residual risk |
A package with six CRITICAL findings about credential harvesting and data exfiltration is fundamentally different from a package with five HIGH findings about missing input validation, even though both "have security issues."
If you're auditing skills manually, CRITICAL density is the fastest signal to check.
The Checklist
Before you publish your next skill to ClawHub:
- [ ] All credentials in environment variables, none in code or config files
- [ ] Permissions scoped to the minimum your skill needs
- [ ] All file paths validated against an allowed directory
- [ ] All external URLs pinned and verified
- [ ] All user/agent input treated as untrusted and sanitized
- [ ] Destructive operations require explicit user confirmation
- [ ] Your
SKILL.mddocuments what the skill accesses and why
None of this is hard. The ecosystem just doesn't make it the default yet. Until it does, the responsibility sits with you, the author.
Full research (all findings, attack taxonomy, and confusion matrix): Distinguishing Malicious From Vulnerable: A Security Analysis of 2,354 ClawHub Skills
Methodology deep-dive (Part 1): How We Analyzed 2,354 ClawHub Skills for Security
The analysis was conducted using trentclaw, a security assessment skill for OpenClaw built by Trent AI (our team).
Top comments (0)