T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- lib/reindex.sh:145
- Finding
- Crafted reindex plans can index files outside the configured drive<![CDATA[ ## Vulnerability Details **File Location**: `lib/reindex.sh:145-193` **Vulnerability Type**: Unvalidated path traversal in reindex plan processing **Risk Level**: High ### Vulnerable Code ```bash local skip desc tags source path skip=$(jq -r ".orphans[$i].skip // false" "$plan") path=$(jq -r ".orphans[$i].path" "$plan") if [[ "$skip" == "true" ]]; then echo " ⏭️ Skip: $path" ((skipped++)) || true ((i++)) || true continue fi desc=$(jq -r ".orphans[$i].desc // \"\"" "$plan") tags=$(jq -r ".orphans[$i].tags // [] | join(\",\")" "$plan") source=$(jq -r ".orphans[$i].source // \"reindex\"" "$plan") local metadata_json correspondent_val metadata_json=$(jq -c ".orphans[$i].metadata // null" "$plan") correspondent_val=$(jq -r ".orphans[$i].correspondent // \"\"" "$plan") if [[ -z "$desc" ]]; then echo " ⚠️ No description for orphan: $path (skipping)" ((skipped++)) || true ((i++)) || true continue fi local date_str date_str=$(jq -r ".orphans[$i].modified // \"$(date +%Y-%m-%d)\"" "$plan") local meta_arg="" [[ "$metadata_json" != "null" ]] && meta_arg="$metadata_json" if [[ "$dry_run" == "true" ]]; then echo " ➕ Would add: $path" echo " desc: $desc" echo " tags: $tags" [[ -n "$meta_arg" ]] && echo " metadata: $meta_arg" [[ -n "$correspondent_val" ]] && echo " correspondent: $correspondent_val" else # Add to index index_add "$date_str" "$path" "$desc" "$tags" "$source" "$meta_arg" "" "$correspondent_val" # Register hash local full="$CLAW_DRIVE_DIR/$path" if [[ -f "$full" ]]; then dedup_register "$full" "$path" fi echo " ✅ Added: $path" fi ``` ### Technical Analysis `reindex_apply` treats `orphans[].path` from the supplied JSON plan as trusted. It does not reject absolute paths or traversal components such as `..`, canonicalize the resulting path, or verify that the final file remains beneath `CLAW_DRIVE_DIR`. For example, the plan value `../../.ssh/id_rsa` causes: ```bash local full= ...[truncated 1932 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Reject absolute paths, empty components, `.` and `..` components, control characters, and paths beginning with `~`. 2. Canonicalize the complete candidate path before any index or hash operation: ```bash drive_root=$(realpath "$CLAW_DRIVE_DIR") || return 1 candidate=$(realpath "$CLAW_DRIVE_DIR/$path") || { echo "Unsafe or missing reindex path: $path" >&2 return 1 } case "$candidate" in "$drive_root"/*) ;; *) echo "Reindex path escapes drive root: $path" >&2 return 1 ;; esac ``` 3. Require the normalized relative path stored in the index to equal the path relative to the canonical drive root. 4. Reject symlink targets outside the drive. If symlinks are unnecessary, reject symlinks entirely. 5. Apply equivalent containment validation during retrieval rather than trusting paths already present in `INDEX.jsonl`. 6. Validate existing index entries before copying or sending files. 7. Add tests for absolute paths, `../` traversal, nested traversal, symlinks, and malformed reindex plans. ]]>
