Add path traversal validation to LocalStore.getFilePath#4738
Open
glitch-ux wants to merge 1 commit intostacklok:mainfrom
Open
Add path traversal validation to LocalStore.getFilePath#4738glitch-ux wants to merge 1 commit intostacklok:mainfrom
glitch-ux wants to merge 1 commit intostacklok:mainfrom
Conversation
LocalStore.getFilePath constructs file paths by joining basePath with a user-provided name but does not validate that the resolved path stays within basePath. A crafted name containing ".." components can escape the designated state directory. Add containment validation using the strings.HasPrefix pattern already established in pkg/fileutils/contained.go (WriteContainedFile). All callers now receive an error for names that resolve outside basePath. Fixes stacklok#4736 Signed-off-by: José Maia <glitch-ux@users.noreply.github.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
LocalStore.getFilePathto prevent crafted state names from escaping the designated directory via..componentsGetReader,GetWriter,CreateExclusive,Delete,Exists) to propagate the validation errorDetails
getFilePathjoinsbasePathwith a user-providednameusingfilepath.Joinbut did not validate that the resolved path stays withinbasePath. A name like../../../etc/passwdwould resolve outside the state directory.The fix uses the
strings.HasPrefix(resolved, basePath + separator)pattern already established inpkg/fileutils/contained.go(WriteContainedFile). The trailing separator prevents prefix collisions (e.g. basePath/state/toolhiveincorrectly matching/state/toolhive-evil/foo).Note: workload-facing code paths already validate names via
fileutils.ValidateWorkloadNameForPath, but the lower-levelLocalStoreis also used for RunConfig and group persistence where that upstream validation may not be applied.Fixes #4736
Test plan
getFilePathcovering valid names and attack patternsCreateExclusiveconflict test