Skip to content

Commit be36414

Browse files
committed
fix: zip slip vulnerability
1 parent ae0d7e9 commit be36414

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

internal/librariangen/generate/generator.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"log/slog"
2424
"os"
2525
"path/filepath"
26+
"strings"
2627

2728
"cloud.google.com/java/internal/librariangen/bazel"
2829
"cloud.google.com/java/internal/librariangen/execv"
@@ -226,6 +227,11 @@ func unzip(src, dest string) error {
226227

227228
for _, f := range r.File {
228229
fpath := filepath.Join(dest, f.Name)
230+
231+
if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) {
232+
return fmt.Errorf("librariangen: illegal file path: %s", fpath)
233+
}
234+
229235
if f.FileInfo().IsDir() {
230236
os.MkdirAll(fpath, os.ModePerm)
231237
continue

internal/librariangen/generate/generator_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,36 @@ func TestUnzip(t *testing.T) {
438438
t.Error("unzip() with read-only destination should return an error")
439439
}
440440
})
441+
442+
t.Run("zip slip vulnerability", func(t *testing.T) {
443+
// Create a zip file with a malicious file path.
444+
maliciousZipPath := filepath.Join(e.outputDir, "malicious.zip")
445+
f, err := os.Create(maliciousZipPath)
446+
if err != nil {
447+
t.Fatalf("failed to create malicious zip file: %v", err)
448+
}
449+
defer f.Close()
450+
zipWriter := zip.NewWriter(f)
451+
if _, err := zipWriter.Create("../../pwned.txt"); err != nil {
452+
t.Fatalf("failed to create malicious file in zip: %v", err)
453+
}
454+
zipWriter.Close()
455+
456+
destDir := filepath.Join(e.outputDir, "unzip-dest")
457+
if err := os.Mkdir(destDir, 0755); err != nil {
458+
t.Fatalf("failed to create unzip dest dir: %v", err)
459+
}
460+
461+
if err := unzip(maliciousZipPath, destDir); err == nil {
462+
t.Error("unzip() with malicious zip file should return an error")
463+
}
464+
465+
// Check that the malicious file was not created.
466+
pwnedFile := filepath.Join(e.tmpDir, "pwned.txt")
467+
if _, err := os.Stat(pwnedFile); !os.IsNotExist(err) {
468+
t.Errorf("malicious file was created at %s", pwnedFile)
469+
}
470+
})
441471
}
442472

443473
func TestMoveFiles(t *testing.T) {

0 commit comments

Comments
 (0)