T09 · Insecure Skill Coding Practices
- Location
scripts/write-file.sh:51- Finding
Workspace Symlinks Permit Writes Outside the Configured Workspace
- Content
View full analysis
Vulnerability Details
File Location:
scripts/write-file.sh:51-65
Vulnerability Type: Symlink-following arbitrary file overwrite
Risk Level: MediumVulnerable Code
bash TARGET="$WORKSPACE/$FILENAME" # --- Check overwrite --- if [ -f "$TARGET" ] && [ "$FORCE" != "true" ]; then echo "ERROR: $FILENAME already exists. Use --force to overwrite." exit 1 fi # --- Validate content --- validate_shell_safety "content" "$CONTENT" check_prompt_injection_tiered "$CONTENT" "$FILENAME" "content" # --- Write file --- mkdir -p "$WORKSPACE" printf '%s\n' "$CONTENT" > "$TARGET"The same filesystem weakness affects fixed-target writes in
scripts/log-training.sh:136-187, scaffold creation inscripts/scaffold.sh:12-13, and predictable rate-limit files inscripts/lib/security.sh:17-44.Technical Analysis
The scripts prevent lexical path traversal by restricting filenames, but they do not reject symbolic links or verify that the resolved destination remains under
OPENCLAW_WORKSPACE. Shell redirection follows symbolic links.In
write-file.sh, an existing symlink to a regular file is protected unless--forceis supplied, after which the external target is overwritten. A dangling symlink is not recognized by[ -f "$TARGET" ]and is followed during creation. Other scripts append to or create fixed filenames without equivalent overwrite protection.This exceeds the minimum privileges needed for workspace management because writes intended to be confined to the workspace can affect arbitrary user-writable locations.
Attack Path
- An attacker gains the ability to prepare, import, or modify a workspace used by the operator.
- The attacker creates a symlink at a recognized destination, such as
SOUL.md,AGENTS.md, orMEMORY.md, pointing to another user-writable file outside the workspace. - The operator invokes setup, forced writing, scaffolding, or training logging.
...[truncated 650 chars]
- Remediation
View remediation
Remediation Suggestions
- Reject symbolic-link destinations using
[ -L "$TARGET" ]before every create, append, move, or overwrite operation. - Resolve the workspace and destination parent with
realpathor an equivalent portable implementation, then verify that the resolved destination remains beneath the canonical workspace path. - Open files with exclusive-creation or no-follow semantics where supported.
- Create replacement files with
mktempinside a trusted workspace directory, set restrictive permissions, and atomically rename them only after revalidating the destination. - Apply the same controls to bootstrap files, daily logs, generated skills, consolidation temporary files, and
.rate-limitstate. - Reject a symlinked workspace root and security-sensitive subdirectories such as
memory,skills, and.rate-limit.
- Reject symbolic-link destinations using
