T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/get-design.sh:12
- Finding
- Style Name Path Traversal Can Escape the Trusted Design Library<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/get-design.sh:12-20` - `scripts/copy-design.sh:14-24` **Vulnerability Type**: Path traversal and insufficient input validation **Risk Level**: Medium ### Vulnerable Code `scripts/get-design.sh:12-20`: ```bash style="$1" design_file="$DESIGN_MD_DIR/$style/DESIGN.md" if [ -f "$design_file" ]; then echo "$design_file" else echo "错误:未找到风格 '$style'" >&2 exit 1 fi ``` `scripts/copy-design.sh:14-24`: ```bash STYLE="$1" TARGET_DIR="${2:-.}" # 获取 DESIGN.md 路径 DESIGN_FILE="$DESIGN_MD_DIR/$STYLE/DESIGN.md" if [ ! -f "$DESIGN_FILE" ]; then echo "错误:未找到风格 '$STYLE'" >&2 echo "可用风格请运行: scripts/list-styles.sh" >&2 exit 1 fi ``` ### Technical Analysis Both scripts insert an untrusted style-name argument directly into a filesystem path. They do not reject path separators, `..` traversal components, absolute paths, or symbolic-link escapes. Quoting the variable prevents shell word splitting and command substitution, but it does not prevent filesystem path traversal. An input containing traversal components can cause the constructed path to resolve outside the intended `design-md` directory. The only security check is whether the resulting path points to a regular file named `DESIGN.md`. This is particularly relevant to the Skill workflow because `SKILL.md` directs the Agent to read the selected `DESIGN.md` as authoritative design guidance. An external attacker-controlled `DESIGN.md` could therefore be introduced into the Agent context and potentially contain prompt-injection instructions. The flaw does not provide unrestricted arbitrary-file reading: the resolved source must be a file named `DESIGN.md`. It also does not independently grant operating-system code execution. Its scope is limited by the filesystem permissions of the process running the Skill. ### Attack Path 1. An attacker causes a crafted style value containing traversal components to be supplied, such as a path ...[truncated 1399 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Restrict style names to one safe directory component: ```bash if [[ ! "$style" =~ ^[A-Za-z0-9._-]+$ ]] || [[ "$style" == "." || "$style" == ".." ]]; then echo "Invalid style name" >&2 exit 1 fi ``` 2. Canonicalize the library root and candidate file, then enforce containment: ```bash DESIGN_ROOT="$(realpath "$SCRIPT_DIR/../design-md")" CANDIDATE="$(realpath -e "$DESIGN_ROOT/$style/DESIGN.md")" || exit 1 case "$CANDIDATE" in "$DESIGN_ROOT"/*) ;; *) echo "Style path escapes the design library" >&2 exit 1 ;; esac ``` 3. Reject symbolic-link escapes. Containment validation must occur after resolving symbolic links with `realpath`. 4. Prefer an allowlist generated from direct child directories of `design-md` that contain `DESIGN.md`. Require the requested value to exactly match an allowlisted name. 5. Apply identical validation in both `get-design.sh` and `copy-design.sh`, ideally through a shared helper to prevent inconsistent fixes. 6. Add regression tests for: - `../` and nested traversal. - Absolute paths. - `.` and `..`. - Embedded path separators. - Symbolic links pointing outside `design-md`. - Valid names containing dots or hyphens, such as `linear.app` and `together.ai`. ]]>
