T09 · Insecure Skill Coding Practices
Error
- Location
- dream-tools.sh:91
- Finding
- Unrestricted Arbitrary File Replacement Through --atomic-write<![CDATA[ ## Vulnerability Details **File Location**: `dream-tools.sh`, lines 91–112 **Vulnerability Type**: Arbitrary file write and replacement **Risk Level**: High ### Vulnerable Code ```bash cmd_atomic_write() { local target="${1:-}" local tmpfile="${2:-}" [[ -z "$target" || -z "$tmpfile" ]] && die "--atomic-write 需要 <target> <tmpfile>" [[ ! -f "$tmpfile" ]] && die "tmp 文件不存在:$tmpfile" # 若目标是 MEMORY.md,检查字符数上限 if [[ "$(realpath "$target" 2>/dev/null)" == "$(realpath "$MEMORY_MD" 2>/dev/null)" ]] || \ [[ "$target" == *"MEMORY.md" ]]; then local size size=$(wc -c < "$tmpfile" | tr -d ' ') if [[ $size -gt $MEMORY_HARD_LIMIT ]]; then die "写入中止:tmp 文件大小 ${size} 字符,超过硬上限 ${MEMORY_HARD_LIMIT}。请先压缩内容。" fi log "MEMORY.md 写入校验通过:${size}/${MEMORY_HARD_LIMIT} 字符" fi ensure_dir "$target" # mv 在同一文件系统上是原子操作 mv "$tmpfile" "$target" log "原子写入完成:$target" } ``` ### Technical Analysis The `--atomic-write` operation accepts caller-controlled source and destination paths without enforcing an allowed directory or destination list. Although special size validation is attempted for paths resembling `MEMORY.md`, every other destination is accepted without scope validation. The function also calls `ensure_dir`, which creates the destination's parent directory, and then uses `mv` to replace the destination. It does not verify that: - The destination is the configured `MEMORY_MD`. - The destination is inside `DREAM_VAULT_PATH` or `OPENCLAW_WORKSPACE`. - The source is an approved temporary file. - The source or destination does not traverse symbolic links. - The destination is a regular file rather than a sensitive configuration or instruction file. The suffix test `[[ "$target" == *"MEMORY.md" ]]` is not a security boundary. It only applies a size limit and still permits an arbitrary path ending in `MEMORY.md`. This behavior contradicts the README claim that file operations ...[truncated 1453 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Restrict destinations to an explicit allowlist, preferably only `MEMORY_MD` for this operation. 2. Canonicalize and validate both paths before performing any write. 3. If multiple destinations are required, ensure each canonical path is either an explicitly approved file or a descendant of an approved root. 4. Reject symbolic links in the source, destination, and all relevant parent path components. 5. Require the temporary file to be a regular file created in the destination directory with restrictive permissions. 6. Use `mktemp` in the target directory so that the final rename occurs on the same filesystem. 7. Avoid suffix-based authorization such as `*"MEMORY.md"`. 8. Refuse destinations containing traversal components or resolving outside the approved roots. 9. Consider replacing the generic interface with a purpose-specific command: ```bash dream-tools.sh --write-memory <approved-temporary-file> ``` 10. Add tests covering absolute paths, `..` traversal, symlink traversal, paths outside the workspace, and unrelated files ending in `MEMORY.md`. ]]>
