T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/synthesize.py:20
- Finding
- Path Traversal Through Unvalidated Persona Name<![CDATA[ ## Vulnerability Details **File Location**: `scripts/synthesize.py:20-21` **Vulnerability Type**: Directory traversal and unintended filesystem modification **Risk Level**: Medium ### Vulnerable Code ```python output_dir = Path(f"personas/{name}") output_dir.mkdir(parents=True, exist_ok=True) ``` ### Technical Analysis The user-controlled `name` argument is incorporated directly into a filesystem path without validation or canonical containment checks. A name containing parent-directory components such as `../` can cause the resolved output directory to escape the intended `personas` directory. The call to `mkdir(parents=True, exist_ok=True)` then creates the attacker-selected directory and any missing parent directories. The operation is constrained only by the operating-system permissions of the process running the Skill. The current implementation does not write `STYLE_MANIFESTO.md`, so this issue does not directly permit arbitrary file-content writes. Nevertheless, arbitrary directory creation is an unauthorized filesystem side effect and could interfere with other applications or prepare directory structures for later attacks. ### Attack Path 1. An attacker invokes the script with a traversal sequence in `--name`, for example: ```bash python scripts/synthesize.py --name "../../../tmp/attacker-controlled" --mode legend ``` 2. The script constructs a path equivalent to: ```text personas/../../../tmp/attacker-controlled ``` 3. `Path.mkdir()` processes the parent-directory components and creates the resulting directory outside the intended `personas` root, provided the running process has permission. 4. An attacker may use this behavior to create unwanted directories in writable locations, disrupt expected filesystem layouts, or establish directories that another process later trusts. ### Impact Assessment Exploitation grants directory-creation capability under the existing privileges of the Skill process. It does no ...[truncated 403 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Restrict persona names to a safe identifier format, such as letters, numbers, spaces, underscores, and hyphens: ```python import re if not re.fullmatch(r"[A-Za-z0-9 _-]{1,100}", name): raise ValueError("Invalid persona name") ``` 2. Resolve the destination against a fixed root and verify containment before performing filesystem operations: ```python personas_root = Path("personas").resolve() output_dir = (personas_root / name).resolve() if output_dir.parent != personas_root: raise ValueError("Persona path escapes the personas directory") output_dir.mkdir(parents=True, exist_ok=True) ``` 3. Reject path separators, `.` and `..` components, control characters, and unexpectedly long values. 4. Run the script with least-privilege filesystem permissions so that unintended writes cannot affect sensitive system or application directories. 5. Add tests covering traversal payloads such as `../outside`, `a/../../outside`, and platform-specific separators. ]]>
