Back to skill

Security audit

creator

Security checks for vulnerabilities and agentic risk

Overview

The skill’s purpose is coherent, but its bundled packaging and initialization scripts have local file-scope weaknesses users should review before installing.

Review before installing if you will use it on untrusted skill folders or automated inputs. Avoid packaging directories you did not inspect, remove symlinks before packaging, and only run the initializer with simple hyphen-case skill names in a controlled output directory.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/init_skill.py:206
Finding
Output Path Traversal in Skill Initializer## Vulnerability Details **File Location**: `scripts/init_skill.py`, lines 206–257 **Vulnerability Type**: Improper path validation and path traversal **Risk Level**: Medium ### Vulnerable Code ```python # Determine skill directory path skill_dir = Path(path).resolve() / skill_name # Check if directory already exists if skill_dir.exists(): print(f"❌ Error: Skill directory already exists: {skill_dir}") return None # Create skill directory try: skill_dir.mkdir(parents=True, exist_ok=False) print(f"✅ Created skill directory: {skill_dir}") except Exception as e: print(f"❌ Error creating directory: {e}") return None # Create SKILL.md from template skill_title = title_case_skill_name(skill_name) skill_content = SKILL_TEMPLATE.format( skill_name=skill_name, skill_title=skill_title ) skill_md_path = skill_dir / 'SKILL.md' try: skill_md_path.write_text(skill_content) print("✅ Created SKILL.md") except Exception as e: print(f"❌ Error creating SKILL.md: {e}") return None # Create resource directories with example files try: scripts_dir = skill_dir / 'scripts' scripts_dir.mkdir(exist_ok=True) example_script = scripts_dir / 'example.py' example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name)) example_script.chmod(0o755) references_dir = skill_dir / 'references' references_dir.mkdir(exist_ok=True) example_reference = references_dir / 'api_reference.md' example_reference.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title)) assets_dir = skill_dir / 'assets' assets_dir.mkdir(exist_ok=True) example_asset = assets_dir / 'example_asset.txt' example_asset.write_text(EXAMPLE_ASSET) except Exception as e: print(f"❌ Error creating resource directories: {e}") return None ``` ### Technical Analysis The `skill_name` command-line argument is appended directly to the resolved base directory without enforcing the naming restrictions displayed by the ...[truncated 1717 chars]
Remediation
## Remediation Suggestions 1. Validate `skill_name` before using it as a path component: - Require a strict expression such as `^[a-z0-9-]{1,64}$`. - Reject leading or trailing hyphens and consecutive hyphens. - Reject absolute paths, path separators, `.` components, and `..` components. 2. Resolve both the base and final paths, then enforce containment: ```python base_dir = Path(path).resolve() if not re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", skill_name): raise ValueError("Invalid skill name") skill_dir = (base_dir / skill_name).resolve() if not skill_dir.is_relative_to(base_dir): raise ValueError("Skill path escapes the output directory") ``` 3. Apply validation inside `init_skill()` rather than only in command-line handling so imported callers receive the same protection. 4. Preserve `exist_ok=False` and fail closed on ambiguous path or permission errors. 5. Add tests covering absolute names, `../` traversal, nested separators, repeated hyphens, and valid skill names.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/package_skill.py:68
Finding
External File Disclosure Through Symlink-Following During Packaging## Vulnerability Details **File Location**: `scripts/package_skill.py`, lines 68–75 **Vulnerability Type**: Symlink traversal and unintended file inclusion **Risk Level**: Medium ### Vulnerable Code ```python with zipfile.ZipFile(skill_filename, 'w', zipfile.ZIP_DEFLATED) as zipf: # Walk through the skill directory for file_path in skill_path.rglob('*'): if file_path.is_file(): # Calculate the relative path within the zip arcname = file_path.relative_to(skill_path.parent) zipf.write(file_path, arcname) print(f" Added: {arcname}") ``` ### Technical Analysis The packager recursively enumerates entries under the selected skill directory but does not reject symbolic links. For a symlink that points to a regular file outside the skill directory, `Path.is_file()` follows the link and returns true. `zipfile.ZipFile.write()` then reads the target's contents, while the archive name is derived from the symlink's in-tree path. Consequently, the generated archive can contain the contents of an arbitrary external file readable by the packaging process, disguised as an ordinary resource within the skill. Validation only checks `SKILL.md` frontmatter and does not inspect symlinks or package membership boundaries. Exploitation requires the attacker to prepare or modify the skill directory before a victim packages and distributes it. ### Attack Path 1. An attacker creates a valid skill directory that passes frontmatter validation. 2. The attacker adds a symlink inside that directory pointing to a sensitive file outside it. 3. A victim runs the documented `package_skill.py` command. 4. `rglob()` encounters the symlink, and `is_file()` accepts it by following its target. 5. `zipf.write()` reads the external target and stores its contents under the symlink's benign in-archive path. 6. The victim shares the resulting `.skill` archive, disclosing the embedded file contents. ### Impact Assessment The issue can ...[truncated 318 chars]
Remediation
## Remediation Suggestions 1. Reject symbolic links before testing whether an entry is a file: ```python for file_path in skill_path.rglob("*"): if file_path.is_symlink(): raise ValueError(f"Symbolic links are not permitted: {file_path}") if not file_path.is_file(): continue ``` 2. Resolve every candidate and verify that it remains under the resolved skill root: ```python skill_root = skill_path.resolve() resolved = file_path.resolve(strict=True) if not resolved.is_relative_to(skill_root): raise ValueError(f"File escapes skill directory: {file_path}") ``` 3. Package only regular files and reject special files such as sockets, devices, and FIFOs. 4. Extend `quick_validate.py` to detect symlinks and out-of-tree targets before packaging begins. 5. Consider an explicit file-type or directory allowlist, maximum individual file size, and maximum total archive size. 6. Add regression tests using symlinks to readable external files and verify that packaging fails without including their contents.
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This second description-behavior mismatch highlights that the skill does more than provide workflow guidance: it directs automated validation and local inspection of skill directories. Even if non-malicious, underdescribed operational behavior reduces transparency and can lead to unanticipated file access and execution when the skill is activated.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
This second description-behavior mismatch highlights that the skill does more than provide workflow guidance: it directs automated validation and local inspection of skill directories. Even if non-malicious, underdescribed operational behavior reduces transparency and can lead to unanticipated file access and execution when the skill is activated.

Self-Modification

High
Category
Rogue Agent
Content
1. Understand the skill with concrete examples
2. Plan reusable skill contents (scripts, references, assets)
3. Initialize the skill (run init_skill.py)
4. Edit the skill (implement resources and write SKILL.md)
5. Package the skill (run package_skill.py)
6. Iterate based on real usage
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.

Self-Modification

High
Category
Rogue Agent
Content
Any example files and directories not needed for the skill should be deleted. The initialization script creates example files in `scripts/`, `references/`, and `assets/` to demonstrate structure, but most skills won't need all of them.

#### Update SKILL.md

**Writing Guidelines:** Always use imperative/infinitive form.
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.

Self-Modification

High
Category
Rogue Agent
Content
# Print next steps
    print(f"\n✅ Skill '{skill_name}' initialized successfully at {skill_dir}")
    print("\nNext steps:")
    print("1. Edit SKILL.md to complete the TODO items and update the description")
    print("2. Customize or delete the example files in scripts/, references/, and assets/")
    print("3. Run the validator when ready to check the skill structure")
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.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill instructs the agent to run local scripts, create directories, validate files, and package archives, but it declares no explicit tool scope or permission boundaries. In a skill system, this increases the chance that the agent will use filesystem, shell, or other powerful capabilities more broadly than the user expected when the skill is triggered.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger description is broad enough that the skill may activate for many requests about creating or updating skills, without clear exclusions for advisory versus operational tasks. Overbroad triggering is dangerous because it can pull in instructions that encourage shell commands, file edits, and packaging steps in contexts where that level of action was not intended.

Static analysis

No suspicious patterns detected.