Back to skill

Security audit

Skill Doctor

Security checks for vulnerabilities and agentic risk

Overview

Skill Doctor is a coherent local auditing tool, but its scanner can be tricked into reading outside a skill directory through symlinks and may print sensitive matching lines.

Install only if you are comfortable with a local audit tool reading installed skill files. Avoid running it on untrusted skill directories that may contain symlinks, and do not paste or share its reports without checking for exposed secrets. The dangerous-command and credential strings in the docs are examples, not active payloads.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
skill_doctor.py:274
Finding

Out-of-Scope File Read Through Symbolic Links

Content
View full analysis
list[dict]: findings = [] for f in sorted(skill.path.rglob("*")): if not f.is_file() or f.suffix.lower() not in SCAN_SUFFIXES: continue if "node_modules" in f.parts or f.name.startswith("."): continue try: lines = f.read_text(encoding="utf-8", errors="replace").splitlines() except Exception: continue for n, line in enumerate(lines, 1): if len(line) > 1000: line = line[:1000] for pat, sev, why in SECURITY_RULES: if pat.search(line): findings.append( { "severity": sev, "file": str(f.relative_to(skill.path)), "line": n, "why": why, "snippet": line.strip()[:140], } ) ``` ### Technical Analysis The security scanner recursively enumerates entries under an installed skill directory and reads each entry that passes the filename-suffix checks. It does not reject symbolic links or verify that the resolved target remains within the scanned skill directory. Python's `Path.is_file()` and `Path.read_text()` follow symbolic links. Consequently, an untrusted installed skill can contain a file-shaped symbolic link whose name has an accepted suffix, such as `.py`, `.md`, or `.sh`, while its target is an arbitrary file outside the skill directory. If a line in the external target matches a rule in `SECURITY_RULES`, up to 140 characters of that line are copied into the generated report. This is particularly relevant because the rules deliberately m ...[truncated 2324 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (14)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · README.md (reported line 10)May include surrounding context.

md
## What it does

- **Conflict detection** — finds skills whose triggers overlap, so you know why the agent sometimes fires the wrong one.
- **Security scan** — flags inline red flags in skill files: remote code execution (`curl … | bash`), credential exfiltration, hard-coded secrets (`ghp_`, `sk-`, `AKIA…`), reads of `~/.ssh`, destructive commands, and more.
- **Version check** — reports which skills are behind their latest ClawHub release (uses the `clawhub` CLI when present).
- **"Which fires?" prediction** — give it any prompt and it ranks which installed skill is most likely to handle it, and warns when the choice is ambiguous.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · README.md (reported line 10)May include surrounding context.

md
## What it does

- **Conflict detection** — finds skills whose triggers overlap, so you know why the agent sometimes fires the wrong one.
- **Security scan** — flags inline red flags in skill files: remote code execution (`curl ... | bash`), credential exfiltration, hard-coded secrets (`ghp_`, `sk-`, `AKIA...`), reads of `~/.ssh`, destructive commands, and more.
- **Version check** — reports which skills are behind their latest ClawHub release (uses the `clawhub` CLI when present).
- **"Which fires?" prediction** — give it any prompt and it ranks which installed skill is most likely to handle it, and warns when the choice is ambiguous.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

md
## Interpreting the results

**Security flags.** Severity is the guide. A `high` flag (curl-piped-to-bash, environment variables posted to a URL, hard-coded `ghp_`/`sk-`/`AKIA` tokens, reads of `~/.ssh`/`.aws/credentials`, reverse-shell patterns, `rm -rf /`) deserves a clear, calm warning and a recommendation to review the exact file and line before trusting the skill. A `medium` flag (`shell=True`, `eval`/`exec`, `chmod 777`) is worth a look but often legitimate. Always cite the file and line and show the snippet so the user can judge for themselves - your job is to surface, not to accuse. A flag is a reason to look, not proof of malice.

**Conflicts.** When two skills share an explicit trigger phrase or have high keyword overlap, the agent can fire the wrong one. The fix is almost always to tighten one skill's `description` so the two stop competing - narrow the broader skill, or add distinguishing context ("for *church* events" vs "for *corporate* events"). Offer to edit the description if the user wants.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · skill_doctor.py (reported line 241)May include surrounding context.

python
## Interpreting the results

**Security flags.** Severity is the guide. A `high` flag (curl-piped-to-bash, environment variables posted to a URL, hard-coded `ghp_`/`sk-`/`AKIA` tokens, reads of `~/.ssh`/`.aws/credentials`, reverse-shell patterns, `rm -rf /`) deserves a clear, calm warning and a recommendation to review the exact file and line before trusting the skill. A `medium` flag (`shell=True`, `eval`/`exec`, `chmod 777`) is worth a look but often legitimate. Always cite the file and line and show the snippet so the user can judge for themselves - your job is to surface, not to accuse. A flag is a reason to look, not proof of malice.

**Conflicts.** When two skills share an explicit trigger phrase or have high keyword overlap, the agent can fire the wrong one. The fix is almost always to tighten one skill's `description` so the two stop competing - narrow the broader skill, or add distinguishing context ("for *church* events" vs "for *corporate* events"). Offer to edit the description if the user wants.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

md
## Interpreting the results

**Security flags.** Severity is the guide. A `high` flag (curl-piped-to-bash, environment variables posted to a URL, hard-coded `ghp_`/`sk-`/`AKIA` tokens, reads of `~/.ssh`/`.aws/credentials`, reverse-shell patterns, `rm -rf /`) deserves a clear, calm warning and a recommendation to review the exact file and line before trusting the skill. A `medium` flag (`shell=True`, `eval`/`exec`, `chmod 777`) is worth a look but often legitimate. Always cite the file and line and show the snippet so the user can judge for themselves - your job is to surface, not to accuse. A flag is a reason to look, not proof of malice.

**Conflicts.** When two skills share an explicit trigger phrase or have high keyword overlap, the agent can fire the wrong one. The fix is almost always to tighten one skill's `description` so the two stop competing - narrow the broader skill, or add distinguishing context ("for *church* events" vs "for *corporate* events"). Offer to edit the description if the user wants.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

md
## Interpreting the results

**Security flags.** Severity is the guide. A `high` flag (curl-piped-to-bash, environment variables posted to a URL, hard-coded `ghp_`/`sk-`/`AKIA` tokens, reads of `~/.ssh`/`.aws/credentials`, reverse-shell patterns, `rm -rf /`) deserves a clear, calm warning and a recommendation to review the exact file and line before trusting the skill. A `medium` flag (`shell=True`, `eval`/`exec`, `chmod 777`) is worth a look but often legitimate. Always cite the file and line and show the snippet so the user can judge for themselves - your job is to surface, not to accuse. A flag is a reason to look, not proof of malice.

**Conflicts.** When two skills share an explicit trigger phrase or have high keyword overlap, the agent can fire the wrong one. The fix is almost always to tighten one skill's `description` so the two stop competing - narrow the broader skill, or add distinguishing context ("for *church* events" vs "for *corporate* events"). Offer to edit the description if the user wants.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

md
## Interpreting the results

**Security flags.** Severity is the guide. A `high` flag (curl-piped-to-bash, environment variables posted to a URL, hard-coded `ghp_`/`sk-`/`AKIA` tokens, reads of `~/.ssh`/`.aws/credentials`, reverse-shell patterns, `rm -rf /`) deserves a clear, calm warning and a recommendation to review the exact file and line before trusting the skill. A `medium` flag (`shell=True`, `eval`/`exec`, `chmod 777`) is worth a look but often legitimate. Always cite the file and line and show the snippet so the user can judge for themselves - your job is to surface, not to accuse. A flag is a reason to look, not proof of malice.

**Conflicts.** When two skills share an explicit trigger phrase or have high keyword overlap, the agent can fire the wrong one. The fix is almost always to tighten one skill's `description` so the two stop competing - narrow the broader skill, or add distinguishing context ("for *church* events" vs "for *corporate* events"). Offer to edit the description if the user wants.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · skill_doctor.py (reported line 241)May include surrounding context.

python
"Decodes base64 and executes it - classic obfuscated payload."),
    (re.compile(r"\beval\s*\(\s*(?:requests|urllib|fetch|http)", re.I), "high",
     "Evaluates content fetched from the network."),
    (re.compile(r"(?:id_rsa|\.ssh/|\.aws/credentials|\.npmrc|\.netrc)"), "high",
     "References private credential files (possible exfiltration)."),
    (re.compile(r"\b(?:ghp_|gho_|github_pat_|sk-[A-Za-z0-9]{16,}|AKIA[0-9A-Z]{16}|xoxb-)"), "high",
     "Looks like a hard-coded secret / API token committed in the skill."),

Credential Access

High
Category
Privilege Escalation
Confidence
80% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · skill_doctor.py (reported line 241)May include surrounding context.

python
"Decodes base64 and executes it - classic obfuscated payload."),
    (re.compile(r"\beval\s*\(\s*(?:requests|urllib|fetch|http)", re.I), "high",
     "Evaluates content fetched from the network."),
    (re.compile(r"(?:id_rsa|\.ssh/|\.aws/credentials|\.npmrc|\.netrc)"), "high",
     "References private credential files (possible exfiltration)."),
    (re.compile(r"\b(?:ghp_|gho_|github_pat_|sk-[A-Za-z0-9]{16,}|AKIA[0-9A-Z]{16}|xoxb-)"), "high",
     "Looks like a hard-coded secret / API token committed in the skill."),

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill documentation instructs the agent to run local Python, inspect installed skills, and optionally query the clawhub CLI, but the manifest declares no permissions or allowed-tools scope. That mismatch can lead to over-broad execution in hosts that infer capabilities from content rather than explicit policy, making file, environment, shell, and possible network access less constrained than users expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger guidance is broad enough that this skill may activate for many generic requests about checking, auditing, reviewing, cleaning up, debugging, or safety. Unintended invocation is risky here because the skill is designed to inspect local skill directories and may run shell commands, so accidental activation expands access to sensitive local metadata unnecessarily.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

md
## Interpreting the results

**Security flags.** Severity is the guide. A `high` flag (curl-piped-to-bash, environment variables posted to a URL, hard-coded `ghp_`/`sk-`/`AKIA` tokens, reads of `~/.ssh`/`.aws/credentials`, reverse-shell patterns, `rm -rf /`) deserves a clear, calm warning and a recommendation to review the exact file and line before trusting the skill. A `medium` flag (`shell=True`, `eval`/`exec`, `chmod 777`) is worth a look but often legitimate. Always cite the file and line and show the snippet so the user can judge for themselves - your job is to surface, not to accuse. A flag is a reason to look, not proof of malice.

**Conflicts.** When two skills share an explicit trigger phrase or have high keyword overlap, the agent can fire the wrong one. The fix is almost always to tighten one skill's `description` so the two stop competing - narrow the broader skill, or add distinguishing context ("for *church* events" vs "for *corporate* events"). Offer to edit the description if the user wants.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · skill_doctor.py (reported line 252)May include surrounding context.

python
(re.compile(r"subprocess\.[A-Za-z_]+\([^)]*shell\s*=\s*True", re.I), "medium",
     "Runs a shell with shell=True - injection risk if input is untrusted."),
    (re.compile(r"\bchmod\s+777\b"), "medium",
     "Sets world-writable permissions."),
    (re.compile(r"\beval\s*\(|\bexec\s*\(", re.I), "medium",
     "Uses eval()/exec() - review what is being executed."),
    (re.compile(r"(?:nc|ncat|netcat)\s+-[a-z]*e\b"), "high",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · skill_doctor.py (reported line 327)May include surrounding context.

python
def _clawhub_latest(name: str) -> str | None:
    for args in (["clawhub", "info", name, "--json"], ["clawhub", "search", name, "--json"]):
        try:
            r = subprocess.run(args, capture_output=True, text=True, timeout=20)
            if r.returncode != 0 or not r.stdout.strip():
                continue
            data = json.loads(r.stdout)