T09 · Insecure Skill Coding Practices
- Location
SKILL.md:43- Finding
Unsanitized Agent Arguments Enable Path Traversal and JSON Injection
- Content
View full analysis
/dev/null || echo "") if [ -n "$SK" ]; then echo "Resuming as $AGENT_ID" echo "Balance: $(curl -s "$API?action=balance" -H "Authorization: Bearer $SK" | jq -r '.chips // "unknown"')" fi fi # Register if no key if [ -z "${SK:-}" ]; then RESP=$(curl -s -X POST "$API" -H "Content-Type: application/json" \ -d "{\"action\":\"register\",\"agent_id\":\"$AGENT_ID\",\"name\":\"$AGENT_NAME\"}") SK=$(echo "$RESP" | jq -r '.secretKey // empty') [ -z "$SK" ] && echo "Registration failed: $RESP" && exit 1 mkdir -p -m 700 "$STORE/$AGENT_ID" echo "$SK" > "$STORE/$AGENT_ID/key"; chmod 600 "$STORE/$AGENT_ID/key" echo "$AGENT_NAME" > "$STORE/$AGENT_ID/name" echo "$AGENT_ID" > "$STORE/active" fi ``` ### Technical Analysis The skill accepts its agent identifier and name from positional shell arguments without validating their format. `AGENT_ID` is subsequently treated as a path component beneath `$HOME/.agentcasino`. Shell quoting prevents ordinary shell metacharacter injection, but it does not prevent filesystem traversal. An identifier containing `../` components can cause `mkdir`, credential writes, and later credential reads to resolve outside the intended per-agent directory. The same untrusted arguments are interpolated directly into a JSON string. Quotes, backslashes, control characters, or JSON syntax in either value are not escaped. A crafted value can therefore create malformed JSON or inject additional JSON properties. The exact interpretation of duplicate or injected properties depends on the remote API parser, but the reques ...[truncated 2038 chars]- Remediation
View remediation
&2 exit 1 ;; esac [ "${#AGENT_ID}" -le 64 ] || { echo "Agent ID is too long" >&2 exit 1 } ``` 2. Canonicalize the destination and verify that it remains beneath `$STORE` before creating or reading files. 3. Reject identifiers containing `/`, `\`, `..`, control characters, or leading path syntax. Apply the same validation when loading the identifier from `$STORE/active`, since persisted state must not be trusted automatically. 4. Construct request bodies with a JSON-aware tool rather than shell interpolation: ```bash REGISTER_BODY=$(jq -n \ --arg agent_id "$AGENT_ID" \ --arg name "$AGENT_NAME" \ '{action: "register", agent_id: $agent_id, name: $name}') RESP=$(curl -sS -X POST "$API" \ -H "Content-Type: application/json" \ --data-binary "$REGISTER_BODY") ``` 5. Use `curl --fail-with-body` and check its exit status so network and HTTP failures cannot be confused with valid registration responses. 6. Create the credential directory only after validation, retain restrictive permissions, and consider atomic writes with a securely created temporary file followed by `mv`. ]]>
