Skip to content

fix: prevent zip-slip path traversal in OCI layer extraction#37

Open
brodmart wants to merge 1 commit intocoder:mainfrom
brodmart:fix/zip-slip-path-traversal
Open

fix: prevent zip-slip path traversal in OCI layer extraction#37
brodmart wants to merge 1 commit intocoder:mainfrom
brodmart:fix/zip-slip-path-traversal

Conversation

@brodmart
Copy link
Copy Markdown

Summary

ExtractFile() in pkg/util/fs_util.go uses filepath.Clean() + filepath.Join() to compute
the extraction path but does not verify the result stays within the root directory. A malicious
tar/OCI layer can include entries like ../../../../etc/cron.d/evil that escape the rootfs and write
to arbitrary host paths.

Root cause

// pkg/util/fs_util.go
cleanedName := filepath.Clean(hdr.Name)
path := filepath.Join(root, cleanedName)  // no prefix check — traversal survives

filepath.Join("/rootfs", "../../../etc/cron.d/evil") resolves to /etc/cron.d/evil.

Fix

Add a prefix check after computing path:

cleanRoot := filepath.Clean(root) + string(filepath.Separator)
if !strings.HasPrefix(filepath.Clean(path)+string(filepath.Separator), cleanRoot) {
    return fmt.Errorf("path traversal detected in tar entry %q escapes root", hdr.Name)
}

Same check applied to TypeSymlink entries (absolute symlink targets only).

Impact

  • CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 CRITICAL
  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory
  • A malicious OCI image pushed to a registry that kaniko pulls from can write arbitrary files to the Kubernetes node running kaniko.

Test

// pkg/util/fs_util_test.go
func TestExtractFileZipSlip(t *testing.T) {
    root := t.TempDir()
    hdr := &tar.Header{
        Name: "../../../etc/evil",
        Typeflag: tar.TypeReg,
        Size: 5,
    }
    err := ExtractFile(root, hdr, bytes.NewReader([]byte("pwned")))
    if err == nil {
        t.Fatal("expected path traversal error, got nil")
    }
}

Add a prefix check in ExtractFile() immediately after computing the
extraction path to ensure tar entries cannot escape the root directory.
Also guard absolute symlink targets in TypeSymlink entries.

CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 CRITICAL
CWE-22: Improper Limitation of a Pathname to a Restricted Directory
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