T09 · Insecure Skill Coding Practices
- Location
SKILL.md:111- Finding
Unvalidated Agent Identifiers Permit Filesystem Path Traversal and Unsafe File Selection
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:111-121,SKILL.md:129-135, andSKILL.md:229-231
Vulnerability Type: Path traversal through unvalidated identifiers
Risk Level: MediumVulnerable Code
SKILL.md:111-121:bash TARGET_AGENT="<agent-id-to-find>" WHISPER_DIR=~/.openclaw/whisper # Fetch from Moltbook (adjust based on actual API) # curl -s "https://api.moltbook.com/m/whisper/search?q=agent:+$TARGET_AGENT" # After fetching, parse the announcement: # - Extract x25519 pubkey, ed25519 pubkey, signature # - Verify signature matches content # - Save to contacts: cat > "$WHISPER_DIR/contacts/${TARGET_AGENT}.json" <<EOFSKILL.md:129-135:bash TARGET_AGENT="<recipient-agent-id>" MESSAGE="<your message here>" WHISPER_DIR=~/.openclaw/whisper MY_AGENT_ID=$(cat "$WHISPER_DIR/identity/agent.id") CONTACT="$WHISPER_DIR/contacts/${TARGET_AGENT}.json" SESSION_KEY="$WHISPER_DIR/sessions/${TARGET_AGENT}.key"SKILL.md:229-231:bash WHISPER_DIR=~/.openclaw/whisper SESSION_KEY="$WHISPER_DIR/sessions/${FROM}.key" KEY_HEX=$(xxd -p "$SESSION_KEY" | tr -d '\n')Technical Analysis
The protocol defines an agent identifier as exactly 16 hexadecimal characters, but the shell workflows do not validate
TARGET_AGENTorFROMbefore incorporating them into filesystem paths.Shell quoting prevents word splitting and wildcard expansion, but it does not neutralize
/or..path components. Consequently, an identifier such as../../some-directory/namechanges the resolved path and can escape the intendedcontactsorsessionsdirectory.The contact-discovery workflow additionally interpolates
TARGET_AGENTdirectly into a JSON heredoc. Characters such as quotation marks, backslashes, or newlines can therefore create malformed JSON or alter the generated JSON structure. This would be prevented implicitly by strict hexade ...[truncated 2041 chars]- Remediation
View remediation
Remediation Suggestions
-
Validate every identifier before using it in a path:
bash validate_agent_id() { local id="$1" [[ "$id" =~ ^[0-9a-f]{16}$ ]] || { echo "Invalid agent identifier" >&2 return 1 } } validate_agent_id "$TARGET_AGENT" || exit 1 validate_agent_id "$FROM" || exit 1 -
Reject identifiers containing separators, traversal components, whitespace, control characters, or unexpected Unicode.
-
Resolve the destination to a canonical path and verify that its parent remains the expected
contactsorsessionsdirectory before reading or writing. -
Create files safely with restrictive permissions and avoid overwriting existing files unless replacement is explicitly intended.
-
Generate contact JSON with a JSON-aware utility rather than a heredoc:
bash jq -n \ --arg agent_id "$TARGET_AGENT" \ --arg x25519_pub "$X25519_PUB" \ --arg ed25519_pub "$ED25519_PUB" \ --arg discovered_at "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \ '{ agent_id: $agent_id, x25519_pub: $x25519_pub, ed25519_pub: $ed25519_pub, discovered_at: $discovered_at, trust_level: "new" }' > "$CONTACT_PATH" -
Apply the same validation at every trust boundary, including parsed message fields, contact imports, API responses, and command arguments.
-
