Skip to content

Prevent basectl clean from escaping the cache through symlinked owner roots #1969

Description

@codeforester

Goal

Ensure basectl clean can never delete files or directories outside the resolved Base cache root, including when a runtime owner or category path contains a symlink.

Background

The cleanup scanner accepts owner roots through Path.is_dir(), which follows symlinks. remove_path checks only whether the final candidate is a symlink before calling shutil.rmtree. A child beneath a symlinked owner root is therefore treated as an ordinary directory.

A focused reproduction created a projects// owner symlink pointing at an unrelated temporary directory. basectl clean --older-than 1s deleted the external run directory and returned success.

Relevant code:

Scope

  • Reject symlinked runtime owner roots and category roots.
  • Resolve every deletion candidate and verify it remains beneath the resolved Base cache root.
  • Fail closed if containment or filesystem metadata cannot be verified.
  • Add focused parent-symlink and candidate-symlink regression tests.
  • Document the cleanup containment guarantee if the public contract needs clarification.

Acceptance Criteria

  • A symlinked owner root cannot cause cleanup outside the cache.
  • A symlinked runs or component-cache directory cannot cause cleanup outside the cache.
  • Normal in-cache cleanup still works for both --older-than and --keep-last.
  • Unsafe candidates are skipped or rejected with an actionable diagnostic.
  • Tests cover symlinks at every relevant parent level.

Validation

  • Focused base_clean pytest coverage.
  • basectl clean dry-run and real deletion against isolated temporary caches.
  • env -u BASE_HOME ./bin/base-test
  • git diff --check

Non-Goals

  • Do not broaden cleanup to user-selected arbitrary paths.
  • Do not change history-index retention.
  • Do not follow symlinks in order to clean their targets.

Project Fields

  • Status: Ready
  • Priority: P1
  • Area: Security
  • Initiative: Contract Hardening
  • Size: M

Agent Assignment

  • Assignee: codeforester

Metadata

Metadata

Assignees

Labels

bugSomething is not workingsecuritySecurity hardening or vulnerability work

Type

No type

Projects

Status
Ready

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions