Skip to content

fix: make staging path-traversal check separator-aware (fail-open on Windows) - #422

Open
mani-mathur-arch wants to merge 2 commits into
mainfrom
mani-mathur_data/mani/fix-staging-path-traversal-windows
Open

fix: make staging path-traversal check separator-aware (fail-open on Windows)#422
mani-mathur-arch wants to merge 2 commits into
mainfrom
mani-mathur_data/mani/fix-staging-path-traversal-windows

Conversation

@mani-mathur-arch

Copy link
Copy Markdown
Collaborator

What

localPathIsAllowed (connection.go) guards staging PUT/GET against a local file escaping the configured stagingAllowedLocalPaths. It did so by rejecting a relative path containing the literal "../":

if !strings.Contains(relativePath, "../") { return true }

filepath.Rel returns OS-native separators, so on Windows an escaping path is ..\x, which the "../" substring never matches. The guard therefore returns true (allowed) for a path outside the allowlist — a fail-open path-traversal check on Windows.

Fix

Compare against filepath.Separator instead: a path is inside the allowed dir iff it is neither ".." nor starts with ".." + separator. Using a prefix check (not Contains) also stops a sibling like ..foo from being mistaken for an escape.

Scope

Only the default Thrift path reaches this code — the kernel/SEA backend rejects staging statements before execStagingOperation, so it never calls this guard.

History

Present since the driver's first commit (Sept 2023) — not a recent regression. The check has always used the hard-coded "../"; it was simply never exercised on Windows because CI was Linux-only.

Testing

The existing TestPathAllowed/Should_not_allow_paths_that_don't_share_directory asserts the escaping path is disallowed. It passed on Linux/macOS and failed on Windows before this change; with the fix it passes on all three. Verified green on the macOS + Windows CI matrix (see #421, which surfaced this).

This pull request and its description were written by Isaac.

localPathIsAllowed guarded against staging PUT/GET escaping the configured
stagingAllowedLocalPaths by rejecting a relative path containing the literal
"../". filepath.Rel returns OS-native separators, so on Windows an escaping
path is "..\\x", which the "../" substring never matches — the guard returned
true (allowed) for a path outside the allowlist. This is a fail-open
path-traversal check on Windows, present since the driver's first commit.

Compare the relative path against filepath.Separator instead: a path is inside
the allowed dir iff it is neither ".." nor starts with ".."+separator. Using a
prefix check (not Contains) also stops a sibling like "..foo" from being
mistaken for an escape.

Only the default Thrift path reaches this code; the kernel/SEA backend rejects
staging statements before execStagingOperation. Surfaced by the new
macOS/Windows CI matrix — the existing TestPathAllowed now passes on Windows.

Co-authored-by: Isaac
Signed-off-by: Mani Kaustubh Mathur <mani.mathur@databricks.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ No issues identified by the review bot.

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.

1 participant