Skip to content

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

Closed
carfeii wants to merge 3 commits into
juicedata:mainfrom
carfeii:fix/filestore-key-path-traversal
Closed

object/file: reject object keys that escape the filestore root#7402
carfeii wants to merge 3 commits into
juicedata:mainfrom
carfeii:fix/filestore-key-path-traversal

Conversation

@carfeii

@carfeii carfeii commented Aug 15, 2026

Copy link
Copy Markdown

Fixes #7401.

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.

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).
Comment thread pkg/object/file_traversal_test.go Outdated
Comment thread pkg/object/file.go Outdated
@jiefenghuang jiefenghuang changed the title fix: reject object keys that escape the filestore root object: reject object keys that escape the filestore root Aug 17, 2026
@jiefenghuang jiefenghuang changed the title object: reject object keys that escape the filestore root object/file: reject object keys that escape the filestore root Aug 17, 2026
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>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ jiefenghuang
❌ Gogs


Gogs seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

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

Copy link
Copy Markdown
Contributor

Hi @carfeii please sign the cla.

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

3 participants