Skip to content

fix(commands): reject symlink follow during skill install - #148

Draft
cursor[bot] wants to merge 2 commits into
mainfrom
cursor/critical-bug-investigation-7002
Draft

cursor[bot] wants to merge 2 commits into
mainfrom
cursor/critical-bug-investigation-7002

Conversation

@cursor

@cursor cursor Bot commented Aug 22, 2026

Copy link
Copy Markdown

Summary

  • skilllite add, skill update-from-source, and OpenClaw import copied skill trees with std::fs::copy / Path::is_dir, both of which follow symlinks.
  • A skill containing passwd-link -> /etc/passwd (or a directory link to $HOME / ~/.ssh) materialized host file contents into .skills/<name>/. That is an install-time arbitrary file read and can leak secrets if the installed tree is committed, shared, or executed.
  • Fix: fail closed on any symlink that would be copied; inspect the source tree before deleting dest so a rejected overwrite cannot wipe an existing skill. Excluded dirs (.venv, node_modules, …) are still skipped even if those names are themselves symlinks.

Task Linkage

  • Task ID: TASK-2026-071
  • Task folder: tasks/TASK-2026-071-reject-skill-install-symlinks/

Injected Specs

  • spec/verification-integrity.md
  • spec/task-artifact-language.md
  • spec/architecture-boundaries.md (if architecture/layering changed)
  • spec/security-nonnegotiables.md (if sandbox/security changed)
  • spec/rust-conventions.md
  • spec/testing-policy.md (required for any code change)
  • spec/docs-sync.md (if behavior/docs/env/commands changed)

Validation Evidence

  • Commands executed:
    • python3 scripts/validate_tasks.py
    • cargo fmt --check
    • cargo clippy --all-targets -- -D warnings
    • cargo test -p skilllite-commands --lib -- copy_skill (5 passed)
    • cargo test -p skilllite --test e2e_minimal (3 passed, including e2e_add_rejects_symlink_to_host_file)
    • cargo test -p skilllite-commands / cargo test -p skilllite / cargo test (0 failed)
  • Key results:
    • Independent repro: copying ln -s /etc/passwd produced a regular file starting with root:x:0:0
    • After the fix, install errors with symlink is not allowed and dest is left untouched

Regression Scope

Docs Sync (EN/ZH)

  • Updated EN + ZH docs
  • Files:
    • README.md
    • docs/zh/README.md

Review Checklist

  • Acceptance criteria in tasks/TASK-2026-071-reject-skill-install-symlinks/TASK.md satisfied (or explicitly deferred)
  • tasks/TASK-2026-071-reject-skill-install-symlinks/STATUS.md updated with latest progress
  • tasks/TASK-2026-071-reject-skill-install-symlinks/REVIEW.md includes merge readiness decision
  • tasks/board.md status is up to date
Open in Web View Automation 

cursoragent and others added 2 commits August 22, 2026 11:12
copy_skill used fs::copy and Path::is_dir, which follow symlinks.
A skill containing a link to /etc/passwd or ~/.ssh was materialized
into .skills/. Fail closed on copied symlinks and inspect the source
before deleting dest so a rejected overwrite cannot wipe an install.

Co-authored-by: EXboy <EXboys@users.noreply.github.com>
Update TASK-2026-071 status, review evidence, and board after
fmt/clippy/test runs.

Co-authored-by: EXboy <EXboys@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant