Skip to content

fix: reject sensitive project paths through symlinks - #1930

Open
mixxer wants to merge 4 commits into
colbymchenry:mainfrom
mixxer:fix/project-path-realpath
Open

mixxer wants to merge 4 commits into
colbymchenry:mainfrom
mixxer:fix/project-path-realpath

Conversation

@mixxer

@mixxer mixxer commented Sep 24, 2026 •

Copy link
Copy Markdown

Summary

Validate both the supplied path and its real path before indexing. Reject symlink aliases of sensitive system directories and sensitive home directories, including a symlinked HOME or a .ssh directory that is itself a symlink. Preserve existing handling of paths that do not exist.

POSIX symlink regressions are platform-gated; Windows path validation is checked separately against the upstream baseline.

Validation

  • Rebased on upstream 6560052a6f856855d3f71eee838fd66ccfa4285d; tested head 0f75b0d0e7076fb858fbbddf346cbc47a5754307.
  • macOS / Node 24.21.0: build passed; full suite: 441 passed / 16 skipped files; 5,715 passed, 263 skipped (portable backend).
  • TypeScript language server: no new diagnostics relative to upstream; changed source files have no errors or warnings. Existing upstream test diagnostics are tracked separately.
  • Linux CI: all 11 jobs passed, including this exact PR head on Node 24. Native kernel checks also passed for fix: preserve Java and Kotlin anonymous inheritance #1927 and fix(java): resolve calls through static fields #1949; integrated main passed on Node 22 and 24.
  • Windows path validation: both this head and upstream passed the two applicable focused tests (ordinary directory and case-insensitive Windows system paths). POSIX symlink tests are skipped on Windows.

@inth3shadows inth3shadows left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked this on Linux by calling validateProjectPath on symlinks I created. Links to /etc, / and /lib, and chained links, are now refused. Real project dirs, symlinked project dirs, missing paths and symlink loops behave as before.

One gap: the ~/.ssh / .aws / .gnupg / .config checks compare the resolved candidate with the unresolved os.homedir(). If $HOME is itself a symlink (for example /home -> /var/home on Fedora Atomic), a link to ~/.ssh resolves to the real path and is accepted. Repro: HOME=<dir>/homelink, where homelink -> realhome. A link to homelink/.ssh returns null (allowed), and so does realhome/.ssh passed directly; only the literal $HOME/.ssh is refused. unsafeIndexRootReason in src/directory.ts already resolves the home dir. Doing the same here (with a fallback when resolution fails), and adding a test with a symlinked HOME, would close it.

Update (2026-09-26): Verified 448b6a6: a link through a symlinked $HOME is refused now, thanks. One narrower case remains. When ~/.ssh is itself a symlink (as dotfile managers like stow set up), a link to it resolves outside home and is accepted: HOME=h, h/.ssh -> d/ssh-real, link -> h/.ssh → validateProjectPath(link) returns null. Resolving each sensitive home dir as well (realpathSync with the same fallback) and adding a test would close it.

@mixxer

mixxer commented Sep 25, 2026

Copy link
Copy Markdown
Author

Addressed the symlinked $HOME gap in 448b6a6. validateProjectPath now checks sensitive home subdirectories against both the lexical home path and its resolved path, with a fallback if resolving home fails. Added a POSIX regression using a symlinked home. __tests__/security.test.ts: 48 passed, 2 skipped; npm run build: passed.

@mixxer

mixxer commented Sep 25, 2026

Copy link
Copy Markdown
Author

Fork follow-up: mixxer/codegraph-aosp#6 carries the symlinked-home fix on the fork's main. Its Node 22/24, native kernel/AOSP, and final CI checks all passed.

@mixxer

mixxer commented Sep 26, 2026

Copy link
Copy Markdown
Author

I saw the 2026-09-26 update to your review and reproduced the ~/.ssh-itself-is-a-symlink case. The new regression failed before the fix because validateProjectPath(link) returned null.

I pushed 34956d8: the validator now checks both the lexical and resolved location of each sensitive home directory. The regression covers a link through ~/.ssh and the resolved target. On macOS, security.test.ts passed (49 passed, 2 skipped) and npm run build passed. The same change is in fork PR #9, where integrated CI is running. Thanks for the precise repro.

@mixxer

mixxer commented Sep 26, 2026

Copy link
Copy Markdown
Author

Final fork status for the symlinked-sensitive-directory follow-up: mixxer/codegraph-aosp#9 is merged at e58d4aa. The post-merge main CI run passed Node 22, Node 24, native kernel/AOSP, and CI checks. Upstream PR #1930 carries the same fix at 34956d8.

@mixxer
mixxer force-pushed the fix/project-path-realpath branch from 34956d8 to 0f75b0d Compare October 4, 2026 15:30

This branch has not been deployed

No deployments
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.

2 participants