Skip to content

fix(evolution): reject path-escaping skill entry points - #127

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

fix(evolution): reject path-escaping skill entry points#127
cursor[bot] wants to merge 2 commits into
mainfrom
cursor/critical-bug-investigation-8329

Conversation

@cursor

@cursor cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

Summary

  • Fixes a critical path escape where LLM-controlled skill.entry_point (and generated skill name) were joined under _evolved/_pending without containment checks. Absolute entry points (e.g. /tmp/pwn.py) replace the skill directory via Path::join, and ../ components escape it before skilllite_fs::write_file writes script content during evolution synthesis.
  • Adds validate_generated_skill_name + script_path_under_skill_dir, wires them into generate/refine/repair/infer, and keeps legitimate nested relatives like scripts/main.py working.
  • Adds regression tests proving absolute/traversal/drive/backslash forms are rejected.

Bug Impact

  • Arbitrary file create/overwrite outside the pending skill tree as the SkillLite process user during evolution run / skill synthesis.
  • Concrete trigger: model returns entry_point: "/tmp/pwn.py" (or ../../../tmp/pwn.py) with script content that passes L3/L4 gates.

Task Linkage

  • Task ID: TASK-2026-075
  • Task folder: tasks/TASK-2026-075-evolution-entry-point-path-safety/

Injected Specs

  • spec/verification-integrity.md
  • spec/task-artifact-language.md
  • spec/security-nonnegotiables.md
  • spec/rust-conventions.md
  • spec/testing-policy.md
  • spec/docs-sync.md (N/A: fail-closed validation only; no user-facing path grammar docs)
  • spec/architecture-boundaries.md (reviewed; no boundary changes)

Validation Evidence

  • Commands executed:
    • cargo test -p skilllite-evolution path_safety -- --nocapture → 5 passed
    • cargo test -p skilllite-evolution → 99 passed
    • cargo clippy -p skilllite-evolution --all-targets -- -D warnings → clean
    • cargo fmt --check -p skilllite-evolution → clean
    • python3 scripts/validate_tasks.py → passed (71 task directories)
  • Key results:
    • Absolute /tmp/pwn.py and traversal ../../../tmp/pwn.py rejected
    • Nested relative scripts/main.py still accepted

Regression Scope

Docs Sync (EN/ZH)

  • Not needed
  • Updated EN + ZH docs
    Files:
    • N/A

Security Review Notes

  • What security policy changed, and why is it needed? Evolution write paths must contain entry_point under the skill directory.
  • Is default behavior more permissive? No — fail-closed.
  • Does this affect SKILLLITE_* config semantics? No.
  • Were tests and EN/ZH docs updated? Tests yes; docs N/A as above.

Review Checklist

  • Acceptance criteria in tasks/TASK-2026-075-evolution-entry-point-path-safety/TASK.md satisfied
  • tasks/TASK-2026-075-evolution-entry-point-path-safety/STATUS.md updated with latest progress
  • tasks/TASK-2026-075-evolution-entry-point-path-safety/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 July 29, 2026 11:16
LLM-controlled entry_point/name values were joined under _pending without
containment checks, so absolute or ../ paths could write scripts outside
the skill directory during synthesis.

Co-authored-by: EXboy <EXboys@users.noreply.github.com>
Record validation results, mark TASK-2026-075 done, and silence the
join_absolute_paths lint in the intentional Path::join precondition test.

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