T09 · Insecure Skill Coding Practices
- Location
ingest.sh:8- Finding
Path Traversal Through an Unvalidated Category Argument
- Content
View full analysis
[category] [slug]" exit 1 fi # Auto-generate slug from URL if not provided if [ -z "$SLUG" ]; then SLUG=$(echo "$URL" | sed 's|https\?://||; s|/.*||; s|[^a-zA-Z0-9-]|-|g' | head -c 60) fi RAW_DIR="$KB_DIR/raw/$CATEGORY" mkdir -p "$RAW_DIR" RAW_FILE="$RAW_DIR/${DATE}-${SLUG}.md" ``` ### Technical Analysis The `CATEGORY` command-line argument is incorporated directly into `RAW_DIR` without validation, normalization, or a canonical containment check. Although the documented categories are limited to `ai-llm`, `engineering`, `products`, and `startups`, the script does not enforce this allowlist. A value containing parent-directory components, such as `../../../../tmp/attacker`, causes the path to resolve outside `$KB_DIR/raw`. The subsequent `mkdir -p` creates the escaped directory, and the heredoc at `ingest.sh:36-49` creates a date-prefixed Markdown file in that location. Shell quoting prevents command substitution and shell metacharacter injection, but it does not prevent filesystem path traversal. ### Attack Path 1. An attacker, untrusted automation, or manipulated Agent controls the category supplied to `ingest.sh`. 2. The caller invokes the script with a traversal value, for example: ```bash ./ingest.sh "https://example.invalid/source" "../../../../tmp/attacker" "payload" ``` 3. `RAW_DIR` resolves outside the intended knowledge-base directory. 4. `mkdir -p "$RAW_DIR"` creates the external directory if permissions allow. 5. The script creates a file such as `/tmp/attacker/YYYY-MM-DD-payload.md`. 6. Attacker-controlled URL and category text are written i ...[truncated 675 chars]- Remediation
View remediation
&2 exit 1 ;; esac ``` 2. Validate the slug independently, even when supplied by the caller: ```bash if [[ ! "$SLUG" =~ ^[A-Za-z0-9][A-Za-z0-9-]{0,59}$ ]]; then echo "ERROR: Invalid slug" >&2 exit 1 fi ``` 3. Canonicalize the base and destination paths and verify that the destination remains beneath the canonical `$KB_DIR/raw` directory before creating anything. 4. Reject path separators, `..`, control characters, empty values, and unexpected Unicode separator characters. 5. Create files with restrictive permissions and fail rather than following unexpected symbolic links. Where supported, use a trusted helper that performs no-follow and exclusive-create operations. 6. Add regression tests covering traversal values, absolute-looking values, symbolic-link destinations, invalid categories, and malformed slugs. ]]>
