Skip to content

Add path traversal validation to LocalStore.getFilePath#4738

Open
glitch-ux wants to merge 1 commit intostacklok:mainfrom
glitch-ux:fix/state-store-path-traversal
Open

Add path traversal validation to LocalStore.getFilePath#4738
glitch-ux wants to merge 1 commit intostacklok:mainfrom
glitch-ux:fix/state-store-path-traversal

Conversation

@glitch-ux
Copy link
Copy Markdown

Summary

  • Add path containment validation in LocalStore.getFilePath to prevent crafted state names from escaping the designated directory via .. components
  • Update all callers (GetReader, GetWriter, CreateExclusive, Delete, Exists) to propagate the validation error
  • Add comprehensive unit tests for the validation and all store operations

Details

getFilePath joins basePath with a user-provided name using filepath.Join but did not validate that the resolved path stays within basePath. A name like ../../../etc/passwd would resolve outside the state directory.

The fix uses the strings.HasPrefix(resolved, basePath + separator) pattern already established in pkg/fileutils/contained.go (WriteContainedFile). The trailing separator prevents prefix collisions (e.g. basePath /state/toolhive incorrectly matching /state/toolhive-evil/foo).

Note: workload-facing code paths already validate names via fileutils.ValidateWorkloadNameForPath, but the lower-level LocalStore is also used for RunConfig and group persistence where that upstream validation may not be applied.

Fixes #4736

Test plan

  • New table-driven tests for getFilePath covering valid names and attack patterns
  • Security-focused test cases for real-world traversal attacks
  • Tests verifying all 5 store operations reject traversal attempts
  • Round-trip test (write → exists → read → list → delete) for valid names
  • CreateExclusive conflict test

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>
Copy link
Copy Markdown
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

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.

LocalStore.getFilePath lacks path traversal validation

1 participant