Back to skill

Security audit

Package Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent skill-packaging tool, but it can delete or move installed skills and generate persistent skill instructions without enough safeguards.

Review before installing. Use only on skills you trust, check source skill directories for symlinks, and back up your skills folder before running create/add/remove commands. Treat generated package SKILL.md and pack.md as untrusted until you inspect them, especially if any packaged sub-skill came from someone else.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/create.py:114
Finding

Nested Symbolic Links Can Cause Unauthorized File Collection

Content
View full analysis
sub/{skill_name}/") ``` ### Technical Analysis The script validates only the top-level source and destination paths. This prevents direct path traversal through command-line skill names, but it does not inspect entries located inside the source skill directory. Python's `shutil.copytree()` uses `symlinks=False` by default. Consequently, symbolic links encountered within the source tree are dereferenced, and the contents of their targets are copied rather than preserving the links. A source skill can therefore contain a symbolic link targeting a file or directory outside `SKILLS_DIR`. The `safe_path()` check does not prevent this condition because it runs before recursive copying and only evaluates the explicitly constructed root paths. It does not validate every object traversed by `copytree()`. ### Attack Path 1. An attacker creates or supplies a skill directory under the skills root. 2. The skill contains a symbolic link pointing to a sensitive file or directory accessible to the user running the script. 3. A victim invokes either: - `create.py create ...` with the c ...[truncated 959 chars]
Remediation
View remediation
None: for entry in root.rglob("*"): if entry.is_symlink(): raise ValueError(f"Symbolic links are not permitted: {entry}") ``` Call this validation immediately before every `copytree()` operation. 2. If symbolic links must be supported, use: ```python shutil.copytree(src, dest, symlinks=True) ``` This preserves links instead of copying target contents. Retained links must still be validated or removed before packaging or distribution because they may resolve outside the package when later consumed. 3. Validate the complete source tree using `os.lstat()` so validation does not itself follow symbolic links. 4. Apply a fail-closed policy: abort the entire operation if a symbolic link, special device, socket, FIFO, or other unsupported filesystem object is detected. 5. Add regression tests covering links to: - Files outside `SKILLS_DIR` - Directories outside `SKILLS_DIR` - Broken links - Relative links containing parent-directory components - Multi-hop symbolic-link chains ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create.py:91
Finding

Unescaped Metadata Can Inject Instructions into Generated Skill Files

Content
View full analysis
str: """Generate a SKILL.md for the package.""" sub_names = ", ".join(s["name"] for s in subs) return f"""--- name: {package_name} description: "This is a skill package containing: {sub_names}. {description}" --- # {package_name.title()} Package This is a skill package bundling {len(subs)} sub-skills: {sub_names}. ## How to Use 1. Read [pack.md](pack.md) to determine which sub-skill matches the current task 2. Read the matching sub-skill: `read_file("skills/{package_name}/sub//SKILL.md")` 3. Follow that sub-skill's instructions """ ``` The generated content is written directly to the package: ```python skill_md = generate_skill_md(package_name, args.description, subs) (package_dir / "SKILL.md").write_text(skill_md, encoding="utf-8") print(f" Generated SKILL.md") ``` ### Technical Analysis The package description supplied through the command line and names read from sub-skill frontmatter are interpolated directly into both YAML frontmatter and Markdown content. No YAML serializer, escaping routine, multiline restriction, or structural validation is applied. Although directory names are restricted by `validate_name()`, the logical sub-skill names come from the `name` field in each copied `SKILL.md` and are not subjected to that validation. The command-line description is also unrestricted. An attacker-controlled value can include quotation marks, line breaks, YAML delimiters, Markdown headings, or agent-directed instructions. Such input can terminate or restructure the generated description and add new content to the generated `SKILL.md`. Because this file is subsequently loaded as an agent skill, injected text can become persiste ...[truncated 1194 chars]
Remediation
View remediation
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- Generate a `SKILL.md` with the provided trigger description and dispatch instructions

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · scripts/create.py (reported line 138)May include surrounding context.

python
# Write pack.md
    write_pack_md(package_dir, subs)

    # Write SKILL.md
    skill_md = generate_skill_md(package_name, args.description, subs)
    (package_dir / "SKILL.md").write_text(skill_md, encoding="utf-8")
    print(f"  Generated SKILL.md")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes file-reading and file-writing behavior through its packaging workflow, but it does not declare any explicit tool scope such as permissions or allowed-tools. In a system that relies on skill metadata for capability gating, this can enable broader-than-expected filesystem access and makes destructive operations harder to review or constrain.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The workflow explicitly says original top-level skill directories are removed and that sub-skills can be removed or moved, but it does not require an explicit warning or confirmation before destructive changes. Because this skill manages a skill library, accidental invocation could cause data loss, broken organization, or removal of working skills.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The create command deletes the original skill directories immediately after copying them into the package, with no confirmation prompt, dry-run mode, backup, or rollback if a later step proves undesirable. This is dangerous because a user can unintentionally lose top-level skills or be left with an unexpected library reorganization that is hard to undo, especially if the copied package is later edited or corrupted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The add command copies a skill into the package and then removes the original source directory without upfront confirmation. Even though this appears intended behavior for packaging, it is still a destructive file operation that can surprise users and cause accidental data loss or break references to the original top-level skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The trigger description explicitly lists English and Chinese phrases as activation phrases, which hard-codes language handling rather than indicating user language preference or broader locale flexibility. This can violate language/locale policy when a skill assumes or enforces specific languages without opt-in or justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.