fix(security): use lstat in claude session discovery to skip symlinks (#153 — gap 2)#157
Conversation
…getagentseal#153) `findDesktopProjectDirs` and `discoverSessions` in `src/providers/claude.ts` walked the session tree with `stat`, which transparently follows symbolic links. A symlink inside `~/.claude/projects/` (or in the macOS / Linux / Windows desktop sessions tree) would let the walk descend anywhere on the filesystem the calling user can read. Switch to `lstat` and explicitly skip symbolic links. Regular directories behave identically; only symlinked entries are now refused. Adds `tests/providers/claude-symlink.test.ts` covering both branches: - a symlinked entry inside the projects dir is dropped from `discoverSessions` output - a regular project directory next to it is still discovered Addresses gap getagentseal#2 from getagentseal#153 ("Walk functions (providers/claude.ts) don't check for symlinks. Use lstat, skip symbolic links."). Gap getagentseal#1 (ANSI sanitization) is in a separate PR. Co-Authored-By: Ora Studio <noreply@oratelecom.net>
|
Hi, The new symlink test creates a directory symlink without Windows-safe options or error handling, which can fail on win32 (often EPERM/EACCES) and break CI/dev runs on Windows. Severity: action required | Category: reliability How to fix: Make symlink creation Windows-safe Agent prompt to fix - you can give this to your LLM of choice:
We noticed a couple of other issues in this PR as well - happy to share if helpful. Found by Qodo. Free code review for open-source maintainers. |
Summary
Addresses gap #2 of #153 ("Walk functions (providers/claude.ts) don't check for symlinks. Use lstat, skip symbolic links.").
findDesktopProjectDirsanddiscoverSessionsinsrc/providers/claude.tswalk the session tree withstat, which transparently follows symbolic links. A symlink under~/.claude/projects/(or anywhere within the macOS / Linux / Windows Claude Desktop sessions trees) lets the walk descend to any path the calling user can read — outside the intended sandbox.Fix
Switch the imports from
stat→lstatand explicitly skip symbolic links:Regular directories behave identically; only symlinks are refused. Three call sites in
claude.ts:findDesktopProjectDirsprojects/*walk infindDesktopProjectDirs~/.claude/projects/walk indiscoverSessionsVerification
tests/providers/claude-symlink.test.tsfails on the unfixed code (verified by stashing the fix and re-running —'shady-link'was discovered)npx tsc --noEmitclean{}-init maps insrc/parser.tsorsrc/providers/(semgrep guard)Out of scope
Gap #1 of #153 (ANSI sanitization of displayed strings) is the companion PR.
The same
stat-vs-lstatpattern exists in other providers (pi,codex,copilot). Per the issue text the symptom was reported inproviders/claude.ts, and a single-provider PR is easier to review than a sweep. Happy to follow up across the other providers in a separate PR if you'd like.Files changed
src/providers/claude.tsstat→lstat; explicit symlink skip at 3 call sitestests/providers/claude-symlink.test.tsVibe Coded by Ousama Ben Younes
Developed With Ora Studio (Claude Code)