T09 · Insecure Skill Coding Practices
Error
- Location
- yandex-tracker.sh:102
- Finding
- Attachment directory restriction can be bypassed through symbolic links<![CDATA[ ## Vulnerability Details **File Location**: `yandex-tracker.sh:102-151`, `yandex-tracker.sh:256-281` **Vulnerability Type**: Symbolic-link path traversal and sandbox bypass **Risk Level**: High ### Vulnerable Code ```bash _resolve_absolute() { local path="$1" [[ -z "$path" ]] && return 1 [[ "$path" == ~* ]] && path="${HOME}${path:1}" if [[ "$path" != /* ]]; then [[ -z "$PWD" ]] && return 1 path="$PWD/$path" fi local result="/" local part while [[ -n "$path" ]]; do path="${path#/}" part="${path%%/*}" path="${path#$part}" path="${path#/}" [[ -z "$part" || "$part" == . ]] && continue if [[ "$part" == .. ]]; then result=$(dirname "$result") continue fi result="${result%/}/$part" done [[ -z "$result" ]] && result="/" echo "$result" } _get_attachment_base() { if [[ -n "${YANDEX_TRACKER_ATTACHMENTS_DIR}" ]]; then local expanded="${YANDEX_TRACKER_ATTACHMENTS_DIR}" [[ "$expanded" == ~* ]] && expanded="${HOME}${expanded:1}" if [[ "$expanded" != /* ]]; then expanded="$PWD/$expanded" fi _resolve_absolute "$expanded" else _resolve_absolute "$PWD" fi } _path_under_base() { local resolved="$1" local base="$2" [[ -z "$resolved" || -z "$base" ]] && return 1 [[ "$resolved" == "$base" ]] && return 0 [[ "$resolved" == "$base/"* ]] && return 0 return 1 } _ensure_attachment_path_allowed() { local kind="$1" # "download" or "upload" local path="$2" local resolved resolved=$(_resolve_absolute "$path") || { echo "Error: invalid path: $path" >&2; return 1; } local base base=$(_get_attachment_base) || { echo "Error: could not determine allowed attachment directory" >&2; return 1; } if ! _path_under_base "$resolved" "$base"; then echo "Error: attachment path must be under the allowed directory (current directory or YANDEX_TRACKER_ATTACHMENTS_DIR)." >&2 return 1 fi return 0 } ``` ```bash attachment_download() { ensure_attachme ...[truncated 3800 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Canonicalize both the configured base directory and upload source with `realpath` or an equivalent facility that resolves symbolic links. 2. Compare canonical paths, including a path-separator boundary, rather than comparing lexically normalized strings. 3. Reject upload source files that are symbolic links. Where practical, also reject paths containing symbolic-link parent components. 4. Recheck the canonical path immediately before use to reduce time-of-check/time-of-use exposure. 5. For downloads, do not pass a user-selected existing path directly to `curl -o`. Create a temporary regular file securely inside the canonical approved directory with `mktemp`, download into it, and move it to a verified destination. 6. Reject an existing destination if it is a symbolic link. Verify that the destination parent directory resolves beneath the approved base. 7. Set restrictive permissions on created directories and files, such as `0700` for private attachment directories and an appropriate restrictive `umask`. 8. Add regression tests covering: - A direct file symlink inside the approved directory. - A symlinked parent directory. - An upload path that resolves outside the base. - A download destination symlink. - Relative paths containing `..`. - Replacement of a checked path between validation and use. ]]>
