You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Recreated on the rewritten main after #1098 was auto-closed during repository maintenance. This carries the same reviewed change set on the new history.
Summary
Normalize the project root before resolving the requested directory.
Compare the real project root and target paths before listing.
Reuse the shared path-containment helper so parent paths and sibling-prefix paths are rejected.
Extend the filesystem abstraction and test mock with realpath.
Add regression tests for the project root, valid child directories, parent traversal, sibling-prefix traversal, and symlink escapes.
This looks like a real, well-scoped security fix. list-directory.ts previously did path.resolve(projectPath, directoryPath) and handed the result straight to readdir with no containment check, so ../-style traversal (and symlink escapes) would work. The fix:
Resolves both the project root and the target path through fs.realpath before comparing, which correctly handles symlink escapes (the link -> ../outside test case is a good catch).
Reuses isPathInside from @codebuff/common/util/path rather than reinventing containment logic.
Extends CodebuffFileSystem and the mock fs (common/src/testing/mocks/filesystem.ts) with realpath, keeping the abstraction consistent for future tools.
Adds targeted regression tests in sdk/src/__tests__/list-directory.test.ts covering root listing, valid child, missing directory (readdir not called), sibling-prefix rejection, parent rejection, and both symlink-escape and symlink-inside cases.
One thing worth double-checking on port: using realpath on the requested path before validating containment means a legitimate but nonexistent path (e.g. a directory the caller is about to create) will throw ENOENT before the containment check runs, changing the error message shape slightly from before — the test for the missing-directory case documents this, so it's likely intentional and acceptable, but flag it to whoever ports this so the change in error message is expected on the private side.
No forbidden paths touched (sdk/, common/ only). Good, minimal diff for the actual behavior change, with tests matching the existing bun:test conventions. This is worth porting as-is.
Rechecked the realpath ordering point. The missing-directory case is intentional and explicitly regression-tested: realpath returns the normal ENOENT-style list error before readdir, while traversal/sibling-prefix/symlink escapes are rejected by containment checks. Targeted list-directory suite: 7 passed, 0 failed. No additional code change was necessary.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
realpath.Fixes #463
Validation
Prior validation before the history rewrite:
bun run --cwd common typecheckbun run --cwd sdk typecheckbun run --cwd sdk test— 518 passed, 0 failedbun test common/src/__tests__/project-file-tree.test.ts— 12 passed, 0 failedgit diff --check