T09 · Insecure Skill Coding Practices
- Location
SKILL.md:40- Finding
Unsafe Predictable State File in a Globally Writable Temporary Directory
- Content
View full analysis
/dev/null || echo 0) NEXT_WORKER=$(echo "$WORKERS" | jq -r ".[$ROBIN_INDEX].address") pilotctl --json send-message "$NEXT_WORKER" \ --data "{\"type\":\"task_assignment\",\"task_id\":\"$TASK_ID\"}" echo "$(( (ROBIN_INDEX + 1) % WORKER_COUNT ))" > /tmp/load-balancer-index.txt ``` ### Technical Analysis The documented round-robin implementation reads from and writes to the fixed path `/tmp/load-balancer-index.txt`. Because `/tmp` is ordinarily writable by all local users, an attacker can pre-create this file, replace it with a symbolic link, or alter its contents between the read and write operations. No ownership, file type, permission, or symbolic-link validation is performed. The state update is also not atomic and does not use locking, allowing concurrent invocations to race and overwrite one another. In addition, the retrieved value is inserted into a `jq` expression without first confirming that it is a valid non-negative integer. ### Attack Path 1. A local attacker predicts the fixed path `/tmp/load-balancer-index.txt`. 2. The attacker either: - writes a manipulated worker index into the file; - replaces the file with a symbolic link to another path writable by the victim; or - modifies the file during a concurrent read-modify-write operation. 3. A user invokes the documented load-balancing commands. 4. The commands consume attacker-controlled routing state and may select an unintended worker. 5. During the final shell redirection, the process follows any attacker-created symbolic link and truncates or overwrites the linked destination using the invoking user's permissions. ### Impact Assessment A successful attack can manipulate worker selection, corrupt round-robin state, disrupt task di ...[truncated 306 chars]- Remediation
View remediation
0 )) || exit 1 (( ROBIN_INDEX < WORKER_COUNT )) || ROBIN_INDEX=0 NEXT_INDEX=$(( (ROBIN_INDEX + 1) % WORKER_COUNT )) TEMP_FILE=$(mktemp "$STATE_DIR/index.XXXXXX") chmod 600 "$TEMP_FILE" printf '%s\n' "$NEXT_INDEX" > "$TEMP_FILE" mv -- "$TEMP_FILE" "$STATE_FILE" ) 9>"$LOCK_FILE" ``` ]]>
