Skip to content

object/file: reject object keys that escape the filestore root - #7425

Merged
jiefenghuang merged 3 commits into
mainfrom
fix/filestore-key-path-traversal-v2
Aug 21, 2026
Merged

object/file: reject object keys that escape the filestore root#7425
jiefenghuang merged 3 commits into
mainfrom
fix/filestore-key-path-traversal-v2

Conversation

@jiefenghuang

Copy link
Copy Markdown
Contributor

Fixes #7401. Supersedes #7402 (rebased onto latest main; original authorship preserved via cherry-pick).

filestore builds each operation's target path by joining an object key directly onto the configured root, with no validation. Since juicefs sync <source> file:///local/destination/ is a documented, ordinary usage pattern, and the object keys enumerated during a sync come from the source backend's own listing (which, unlike a real local filesystem walk, has no character restrictions), a key containing ../ segments causes data to be written outside the intended local destination directory.

Adds safePath, wrapping the existing path helper with a containment check (using filepath.Rel against the storage root, or the root's parent directory when root is used as a flat-namespace prefix rather than a directory, matching both of path's existing modes). Updates all 8 call sites (Put, Get, Head, Delete, Chmod, Chown, Symlink, Readlink) to use it.

Adds a regression test (TestFilestoreRejectsKeyPathTraversal).

Verified against a scratch store: a key of ../outside/pwned.txt written via Put escaped the configured root before this fix, confirmed via direct filesystem inspection; after the fix, the same call is rejected with a clear error and no file escapes. go test ./pkg/object/... ./pkg/sync/... all pass.


This PR replaces #7402, applying the same three commits (by @carfeii) on top of the current main.

Gogs and others added 3 commits August 20, 2026 16:53
filestore builds each operation's target path by joining an object
key directly onto the configured root, with no validation. Since
juicefs sync <source> file:///local/destination/ is a documented,
ordinary usage pattern, and the object keys enumerated during a sync
come from the source backend's own listing (which, unlike a real
local filesystem walk, has no character restrictions), a key
containing ../ segments causes data to be written outside the
intended local destination directory.

Add safePath, wrapping the existing path helper with a containment
check (using filepath.Rel against the storage root, or the root's
parent directory when root is used as a flat-namespace prefix rather
than a directory, matching both of path's existing modes). Update all
8 call sites (Put, Get, Head, Delete, Chmod, Chown, Symlink,
Readlink) to use it.

Adds a regression test (TestFilestoreRejectsKeyPathTraversal).
Route filestore path resolution through one checked helper so Chtimes and future callers reject keys that escape the storage root. Also reject escaping List prefixes before opening local directories.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move the new filestore traversal coverage into file_test.go and update the new test file header year to match the repository license format.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jiefenghuang
jiefenghuang requested a review from zxh326 August 20, 2026 08:58
@jiefenghuang
jiefenghuang merged commit 0bcd70b into main Aug 21, 2026
34 checks passed
@jiefenghuang
jiefenghuang deleted the fix/filestore-key-path-traversal-v2 branch August 21, 2026 02:12
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.

Local filestore object backend writes outside its configured root via a crafted object key

2 participants