T09 · Insecure Skill Coding Practices
- Location
scripts/setup-team.sh:12- Finding
Unvalidated Agent IDs Allow Path Traversal and Workspace File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/setup-team.sh, lines 12–15 and 34–45
Vulnerability Type: Path traversal, unsafe file overwrite, and instruction-file injection
Risk Level: MediumVulnerable Code
bash WRITER_ID=$1 shift OTHER_ROLES=("$@") BASE_DIR="$HOME/.openclaw" WRITER_WS="$BASE_DIR/workspace-$WRITER_ID"bash for role in "${OTHER_ROLES[@]}"; do echo "=== Creating shell workspace: $role ===" SHELL_WS="$BASE_DIR/workspace-$role" mkdir -p "$SHELL_WS" # Create absolute path symlinks ln -sf "$WRITER_WS/OUTPUT" "$SHELL_WS/OUTPUT" ln -sf "$WRITER_WS/KNOWLEDGE" "$SHELL_WS/KNOWLEDGE" cat > "$SHELL_WS/TOOLS.md" << EOF # TOOLS.md - $roleTechnical Analysis
The script incorporates the user-supplied writer and role IDs directly into filesystem paths without validating their syntax or confirming that the resolved destinations remain beneath
$HOME/.openclaw.Although the variables are quoted, quoting only prevents shell word splitting and wildcard expansion. It does not prevent path traversal. An ID containing
/and..path components can makeWRITER_WSorSHELL_WSresolve outside the intended OpenClaw workspace hierarchy.The script performs security-sensitive operations at the resulting locations:
mkdir -pcreates directories.ln -sfreplacesOUTPUTandKNOWLEDGEentries with symbolic links.cat > "$SHELL_WS/TOOLS.md"truncates and overwrites a file. If the destination is an existing symbolic link, normal shell redirection can follow it.- The role value is embedded in an unquoted here-document, allowing newline-containing IDs to inject attacker-controlled text into the generated Agent instruction file.
Exploitation requires the attacker to control or influence arguments passed to the setup script. The resulting operations remain subject to the invoking user's filesystem permissions.
Attack Path
- An attacker convinces a user or automation process to invoke ...[truncated 1453 chars]
- Remediation
View remediation
Remediation Suggestions
- Apply a strict allowlist to every agent ID before using it:
bash validate_id() { local id=$1 if [[ ! "$id" =~ ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$ ]]; then printf 'Invalid agent ID: %q\n' "$id" >&2 exit 1 fi } validate_id "$WRITER_ID" for role in "${OTHER_ROLES[@]}"; do validate_id "$role" doneThis rejects path separators, traversal components, whitespace, control characters, and newline-based instruction injection.
-
Canonicalize and enforce path containment. Resolve the OpenClaw base directory and each destination, then verify that every destination begins with the canonical base path followed by
/. Do not rely only on string concatenation. -
Reject unexpected existing files and symbolic links. Before writing
TOOLS.mdor replacingOUTPUTandKNOWLEDGE, uselstat-equivalent checks such as[[ -L ... ]]and[[ -e ... ]]. Abort unless overwrite behavior was explicitly requested and validated. -
Avoid following a pre-existing
TOOLS.mdsymlink. Create a temporary regular file securely within the validated workspace, verify the final destination is not a symlink, and atomically rename the file into place. -
Use fixed templates for generated instructions. Do not interpolate untrusted identifiers into instruction content. If an identifier must be displayed, validate it first and render it as inert data.
-
Use safe, idempotent link handling. Confirm that existing links already point to the expected writer directories; otherwise stop and require explicit user confirmation rather than unconditionally using
ln -sf. -
Add negative security tests covering IDs containing
../, absolute-path fragments, slashes, backslashes, spaces, shell metacharacters, newline characters, and control characters.
