From 6e4fded92418bc281a9fec0d73b59bc24af7ffdc Mon Sep 17 00:00:00 2001 From: Zack Brady Date: Sat, 15 Aug 2026 08:21:02 -0400 Subject: [PATCH] fixed bug with store sync extraction into unwritable directory --- cmd/hauler/cli/store/sync.go | 4 ++-- internal/mapper/filestore.go | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/hauler/cli/store/sync.go b/cmd/hauler/cli/store/sync.go index 37a4552..37f0e63 100644 --- a/cmd/hauler/cli/store/sync.go +++ b/cmd/hauler/cli/store/sync.go @@ -163,12 +163,12 @@ func SyncCmd(ctx context.Context, o *flags.SyncOpts, s *store.Layout, rso *flags if err != nil { return fmt.Errorf("failed to fetch product manifest for [%s]: %w", productName, err) } - err = ExtractCmd(ctx, &flags.ExtractOpts{StoreRootOpts: o.StoreRootOpts}, s, fmt.Sprintf("hauler/%s-manifest.yaml:%s", parts[0], tag)) + err = ExtractCmd(ctx, &flags.ExtractOpts{StoreRootOpts: o.StoreRootOpts, DestinationDir: tempDir}, s, fmt.Sprintf("hauler/%s-manifest.yaml:%s", parts[0], tag)) if err != nil { return err } fileName := fmt.Sprintf("%s-manifest.yaml", parts[0]) - fi, err := os.Open(fileName) + fi, err := os.Open(filepath.Join(tempDir, fileName)) if err != nil { return err } diff --git a/internal/mapper/filestore.go b/internal/mapper/filestore.go index d2c56d3..6b9a720 100644 --- a/internal/mapper/filestore.go +++ b/internal/mapper/filestore.go @@ -89,8 +89,10 @@ func (s *pusher) Push(ctx context.Context, desc ocispec.Descriptor) (ccontent.Wr } fullFileName := filepath.Join(destDir, filename) - // Guard against path traversal (e.g. filename containing "../") - if !strings.HasPrefix(fullFileName, destDir+string(filepath.Separator)) { + // Guard against path traversal (e.g. "../"). filepath.Rel handles this + // correctly even when destDir is "/", unlike a plain prefix check. + rel, err := filepath.Rel(destDir, fullFileName) + if err != nil || rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) { return nil, fmt.Errorf("path_traversal_disallowed: %q resolves outside destination dir", filename) }