Back to skill

Security audit

Skill创建工厂

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed skill generator, but its script can write caller-supplied files outside the intended skill folder.

Only install this after the filename/path handling is fixed. Do not feed it untrusted skill configs, and restrict output locations because a crafted resource name could overwrite files the running process can access.

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

Error
Location
scripts/create_skill.py:91
Finding
Arbitrary File Write Through Unsanitized Resource Names## Vulnerability Details **File Location**: `scripts/create_skill.py:91-131` **Vulnerability Type**: Path traversal and unrestricted file write **Risk Level**: High ### Vulnerable Code ```python # Create scripts if scripts: scripts_dir = skill_path / "scripts" scripts_dir.mkdir(exist_ok=True) for script in scripts: script_name = script.get("name", "script.py") script_content = script.get("content", "") script_path = scripts_dir / script_name script_path.write_text(script_content, encoding="utf-8") # Make executable if Python/Shell if script_name.endswith(('.py', '.sh')): script_path.chmod(0o755) result["files_created"].append(f"scripts/{script_name}") # Create references if references: refs_dir = skill_path / "references" refs_dir.mkdir(exist_ok=True) for ref in references: ref_name = ref.get("name", "reference.md") ref_content = ref.get("content", "") ref_path = refs_dir / ref_name ref_path.write_text(ref_content, encoding="utf-8") result["files_created"].append(f"references/{ref_name}") # Create assets if assets: assets_dir = skill_path / "assets" assets_dir.mkdir(exist_ok=True) for asset in assets: asset_name = asset.get("name", "asset") asset_content = asset.get("content", "") asset_path = assets_dir / asset_name # Handle binary content (base64) if asset.get("encoding") == "base64": import base64 asset_path.write_bytes(base64.b64decode(asset_content)) else: asset_path.write_text(asset_content, encoding="utf-8") ...[truncated 2556 chars]
Remediation
## Remediation Suggestions - Treat all resource names as untrusted input. - Reject absolute paths, empty names, `.` and `..` components, path separators, and platform-specific alternate separators. - If nested resource paths are unnecessary, require a basename and enforce a conservative allowlist such as letters, digits, periods, underscores, and hyphens. - Resolve the resource root and destination before writing, then verify containment: ```python def safe_destination(root: Path, supplied_name: str) -> Path: if not supplied_name or Path(supplied_name).is_absolute(): raise ValueError("Resource name must be a non-empty relative path") root = root.resolve() destination = (root / supplied_name).resolve() try: destination.relative_to(root) except ValueError as exc: raise ValueError("Resource path escapes its destination directory") from exc return destination ``` - Account for symbolic-link attacks when the output tree may be writable by another user. Avoid following existing symlinks and consider descriptor-relative, no-follow file operations on supported platforms. - Create files with exclusive semantics when overwriting existing files is not required. - Apply executable permissions only after validating the destination and only when explicitly requested, rather than inferring executability solely from a filename extension. - Add tests covering absolute paths, repeated traversal components, mixed path separators, symbolic links, and valid filenames.
Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (9)

Ae1

High
Category
analysis-evasion
Content
"files_created": ["SKILL.md", "scripts/main.py"]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
parser.add_argument("--description", type=str, help="Skill description")
    parser.add_argument("--instructions", type=str, help="Skill instructions (markdown)")
    parser.add_argument("--output-dir", type=str, help="Output directory")
    parser.add_argument("--no-validate", action="store_true", help="Skip validation")
    parser.add_argument("--no-package", action="store_true", help="Skip packaging")
    
    args = parser.parse_args()
Confidence
88% confidence
Finding
Exposing a --no-validate flag allows callers to disable the only explicit safety gate before packaging and distributing generated skills. In the context of a skill factory that may be called programmatically by other skills or automation, this increases the chance that malicious or unsafe skill content is created and propagated without review.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill clearly describes capabilities to create directories, write multiple files, and run validation/packaging, yet it declares no explicit tool scope such as permissions or allowed-tools. That mismatch increases the risk that callers or agents invoke file-system and shell-like actions without clear restriction boundaries, enabling broader-than-expected code generation and persistence on disk.

Session Persistence

Medium
Category
Rogue Agent
Content
## Workflow

1. **Validate parameters** - Check skill_name format, required fields
2. **Create directory structure** - `skill_name/` with appropriate subdirectories
3. **Generate SKILL.md** - Write frontmatter + instructions
4. **Create resources** - Write scripts, references, assets if provided
5. **Validate** - Run skill validation (optional, default: on)
Confidence
88% confidence
Finding
The skill is intentionally designed to persist new content across the session by creating skill directories, writing instructions/scripts, and packaging outputs. In context this persistence is the primary function, but it is still security-relevant because untrusted upstream input could be turned into durable agent capabilities or artifacts that survive beyond the current interaction.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The specification says the description is the primary triggering mechanism, but it does not require strict scope boundaries, negative triggers, or exclusion criteria. In a callable skill factory, that encourages broad or ambiguous descriptions that can cause unintended skill activation, misrouting, or prompt-surface expansion when downstream skills are auto-generated from this guidance.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script writes attacker-controlled files and directories to disk, including arbitrary script, reference, and asset filenames, without confirmation or path confinement checks on nested file names. Because child entry names such as scripts[].name or assets[].name are not validated, an attacker can use path traversal like ../../ to escape the intended subdirectories and overwrite other files accessible to the process.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if validate:
            validate_script = SKILL_CREATOR_DIR / "scripts" / "package_skill.py"
            if validate_script.exists():
                proc = subprocess.run(
                    ["python3", str(validate_script), str(skill_path), "--validate-only"],
                    capture_output=True,
                    text=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if package:
            package_script = SKILL_CREATOR_DIR / "scripts" / "package_skill.py"
            if package_script.exists():
                proc = subprocess.run(
                    ["python3", str(package_script), str(skill_path), str(output_dir)],
                    capture_output=True,
                    text=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Low
Confidence
92% confidence
Finding
The skill advertises creating files, directories, and packaged artifacts but does not prominently warn that it will persist data to disk and generate distributable outputs. This can mislead users or upstream skills into triggering side effects they did not fully intend, especially in automation chains where generated artifacts may later be executed or shared.

Static analysis

No suspicious patterns detected.