T09 · Insecure Skill Coding Practices
- Location
scripts/count-tool-use.sh:7- Finding
Predictable Temporary Files Permit Symlink Attacks and Session-State Manipulation
- Content
View full analysis
"$COUNTER_FILE" else count=$(($(cat "$COUNTER_FILE") + 1)) echo $count > "$COUNTER_FILE" fi # Log tool name if [ -n "$TOOL_NAME" ] && [ "$TOOL_NAME" != "null" ]; then echo "$TOOL_NAME" >> "$TOOLS_FILE" fi ``` The Stop hook reconstructs and trusts the same paths: ```bash COUNTER_FILE="/tmp/claude_skill_counter_${SESSION_ID}" TOOLS_FILE="/tmp/claude_skill_tools_${SESSION_ID}" if [ ! -f "$COUNTER_FILE" ]; then exit 0 fi count=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0) if [ "$count" -ge "$THRESHOLD" ]; then # Get unique tool list if [ -f "$TOOLS_FILE" ]; then tools=$(sort "$TOOLS_FILE" | uniq | tr '\n' ',' | sed 's/,$//') unique_count=$(sort "$TOOLS_FILE" | uniq | wc -l | tr -d ' ') else tools="unknown" unique_count=0 fi fi rm -f "$COUNTER_FILE" "$TOOLS_FILE" ``` ### Technical Analysis The hooks store state under globally writable `/tmp` using filenames derived directly from a session identifier. They do not use `mktemp`, a private per-user directory, exclusive creation, restrictive permissions, ownership checks, or symlink checks. Shell output redirections follow symbolic links. Consequently, another local process running in the same security context—or a different local account where the platform's temporary-directory protections do not prevent the operation—may pre-create a matching path as a symbolic link. Subsequent hook execution can truncate or append to the symlink target if the Claude Code user has permission to write that target. An attacker can also create ordinary counter and too ...[truncated 1762 chars]- Remediation
View remediation
