T09 · Insecure Skill Coding Practices
- Location
SKILL.md:85- Finding
Predictable Lock File in Shared Temporary Directory Allows Symlink-Based File Truncation
- Content
View full analysis
"$LOCKFILE" flock -n 200 || { echo "另一个实例正在运行"; exit 0; } ``` The same pattern is recommended again at lines 164–166: ```bash LOCKFILE="/tmp/workflow-${NAME}.lock" exec 200>"$LOCKFILE" flock -n 200 || { echo "另一个实例正在运行"; exit 0; } ``` ### Technical Analysis The documented locking pattern creates or opens a predictable file directly under the globally writable `/tmp` directory. The shell redirection: ```bash exec 200>"$LOCKFILE" ``` opens the path with truncation before `flock` attempts to acquire a lock. Standard shell redirection follows symbolic links. Consequently, another local user may pre-create the predictable lock-file path as a symbolic link to a file writable by the account running the workflow. When the workflow starts, the redirection follows that symbolic link and truncates the linked target. The subsequent `flock` operation occurs too late to prevent the truncation. The fixed `workflow-my-first-flow.lock` name is directly predictable. The variable form is also predictable when the workflow name is known or can be inferred. This is a time-of-check/time-of-use and unsafe temporary-file issue rather than a defect in `flock` itself. ### Attack Path 1. A local attacker identifies or predicts the workflow name. 2. The attacker creates the expected lock path as a symbolic link, for example: ```bash ln -s /path/to/agent-writable/file /tmp/workflow-my-first-flow.lock ``` 3. The user or Agent executes the workflow according to the Skill instructions. 4. The shell evaluates `exec 200>"$LOCKFILE"`. 5. The redirection follows the attacker-controlled symbolic link and truncates the target file. 6. `flock` is invoked only after the destructive file-open ope ...[truncated 834 chars]- Remediation
View remediation
&2 exit 1 ;; esac ``` 4. **Open the lock only inside the protected directory:** ```bash LOCKFILE="$LOCKDIR/workflow-$NAME.lock" exec 200>"$LOCKFILE" flock -n 200 || { echo "Another instance is running" >&2 exit 0 } ``` 5. **For stronger hardening, prevent symbolic-link following explicitly.** Use a small helper that opens the file with `O_NOFOLLOW`, or use an atomic `mkdir`-based locking design within the private directory. 6. **Document cleanup and ownership checks.** Before using an existing lock directory, verify that it is owned by the current user and is not writable by group members or other users. ]]>
