T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/create_agent.sh:4
- Finding
- Unvalidated Agent Name and Role Enable Path Traversal and Skill Instruction Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/create_agent.sh`, lines 4-16 **Vulnerability Type**: Path traversal, unsafe file overwrite, and generated instruction injection **Risk Level**: Medium ### Vulnerable Code ```bash NAME=$1 ROLE=$2 DIR="agents/$NAME" mkdir -p "$DIR/inbox" "$DIR/outbox" "$DIR/workspace" cat <<EOM > "$DIR/SKILL.md" --- name: $NAME description: $ROLE --- # Mission You are $NAME. Your role is: $ROLE. Read instructions from ./inbox and write outputs to ./outbox. EOM ``` ### Technical Analysis The script accepts `NAME` and `ROLE` as untrusted command-line arguments without validation or encoding. `NAME` is directly concatenated into `DIR`. Although filesystem uses are quoted, quoting only prevents shell word splitting and does not prevent path traversal. A value containing directory separators or `..` components can resolve outside the intended `agents/` directory. The script then creates directories at the resolved location and overwrites a file named `SKILL.md`. Both `NAME` and `ROLE` are also interpolated directly into YAML metadata and natural-language instructions through an unquoted heredoc. An argument containing newline characters can terminate the expected field and inject additional YAML properties, Markdown sections, or agent instructions. If the generated skill is later loaded, those injected instructions may alter the receiving agent's behavior. The issue does not independently bypass operating-system permissions. Exploitation requires control over the script arguments, and all filesystem effects remain limited to locations writable by the account executing the script. ### Attack Path 1. An attacker gains control over, or can influence, the `NAME` or `ROLE` argument supplied to `scripts/create_agent.sh`. 2. For the filesystem attack, the attacker supplies a `NAME` containing traversal components such as `../`. 3. The expression `agents/$NAME` resolves outside the intended agent root. 4. `mkdir -p` crea ...[truncated 1177 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate `NAME` against a strict allowlist before using it: ```bash if [[ ! "$NAME" =~ ^[A-Za-z0-9_-]+$ ]]; then echo "Invalid agent name" >&2 exit 1 fi ``` Reject empty values, path separators, `..`, whitespace, newlines, control characters, and shell metacharacters. 2. Define an absolute, trusted agent root and verify the resolved destination remains beneath it: ```bash AGENT_ROOT="$(realpath -m "./agents")" DIR="$(realpath -m "$AGENT_ROOT/$NAME")" case "$DIR/" in "$AGENT_ROOT/"*) ;; *) echo "Destination escapes the agent root" >&2 exit 1 ;; esac ``` 3. Validate `ROLE` as a single-line data field. Reject carriage returns, newlines, and control characters if multiline roles are not required. 4. Generate YAML using a serializer that correctly quotes and escapes scalar values. Do not directly interpolate untrusted values into executable agent instructions. 5. Refuse to overwrite an existing `SKILL.md` unless the caller supplies an explicit, trusted overwrite option: ```bash if [[ -e "$DIR/SKILL.md" ]]; then echo "SKILL.md already exists" >&2 exit 1 fi ``` 6. Use restrictive permissions when creating agent directories and files, and write to a temporary file followed by an atomic rename after validation succeeds. 7. Add tests covering traversal strings, absolute paths, embedded newlines, YAML delimiters, control characters, and attempts to overwrite existing skills. ]]>
