From 999365b34d0bc5e50b670386c98111025a37997a Mon Sep 17 00:00:00 2001 From: Matthew Burket Date: Fri, 1 May 2026 10:22:21 -0500 Subject: [PATCH] Fix possible zipslip in image/docker.go Created with Cursor --- image/docker.go | 8 +++++++- image/docker_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/image/docker.go b/image/docker.go index d3e26ff..18a9d4b 100644 --- a/image/docker.go +++ b/image/docker.go @@ -42,7 +42,13 @@ func NewDockerLocalImage(ctx context.Context, exportDir string, importDir string tr := tar.NewReader(f) hdr, err := tr.Next() for ; err == nil; hdr, err = tr.Next() { - dir, fn := filepath.Split(hdr.Name) + // Docker export tar entries use slash-separated names; reject Tar Slip paths. + cleanName := filepath.Clean(filepath.FromSlash(hdr.Name)) + if !filepath.IsLocal(cleanName) { + return nil, fmt.Errorf("invalid tar entry path %q", hdr.Name) + } + + dir, fn := filepath.Split(cleanName) if strings.HasSuffix(fn, ".tar") { layerFilePath := "" diff --git a/image/docker_test.go b/image/docker_test.go index 920de13..4c4b7f8 100644 --- a/image/docker_test.go +++ b/image/docker_test.go @@ -1,9 +1,11 @@ package image import ( + "archive/tar" "context" "fmt" "os" + "path/filepath" "testing" ) @@ -26,3 +28,38 @@ func TestFromExported(t *testing.T) { } fmt.Println(di) } + +func TestNewDockerLocalImage_rejectsTarSlipPaths(t *testing.T) { + tmp := t.TempDir() + tarPath := filepath.Join(tmp, "export.tar") + f, err := os.Create(tarPath) + if err != nil { + t.Fatal(err) + } + tw := tar.NewWriter(f) + hdr := &tar.Header{ + Name: "../../../outside/evil.tar", + Mode: 0600, + Size: 0, + Typeflag: tar.TypeReg, + } + if err := tw.WriteHeader(hdr); err != nil { + t.Fatal(err) + } + if err := tw.Close(); err != nil { + t.Fatal(err) + } + if err := f.Close(); err != nil { + t.Fatal(err) + } + + importDir := filepath.Join(tmp, "import") + if err := os.MkdirAll(importDir, 0700); err != nil { + t.Fatal(err) + } + + _, err = NewDockerLocalImage(context.Background(), tarPath, importDir) + if err == nil { + t.Fatal("expected error for path traversal in tar entry name") + } +}