Skip to content
1525

1525

github.com • September 20, 2026

Gopeed's archive extraction has three independent zip-slip vectors, all in the pkg/download/ package.

Vector 1: 7z Multi-Part — Full Arbitrary File Write

pkg/download/extract_7z.go:46 uses f.Name from bodgit/sevenzip directly in filepath.Join with zero path sanitization:

Neither bodgit/sevenzip nor Gopeed sanitizes f.Name . An entry named ../../evil.txt writes to an arbitrary path outside the extraction directory. This path is reached when a user downloads or extracts any .7z.001 multi-part archive.

Vector 2: Directory Creation Escape in All Formats

pkg/download/extract.go:284-296 handles directory entries BEFORE the path sanitization check:

The mholt/archives library explicitly documents that NameInArchive is not sanitized (archives.go:32-33: "should not be trusted at face value"). A directory entry named ../../escaped/ in any zip, tar, tar.gz, or rar archive creates directories outside the extraction target. This affects all formats routed through extractFile via createExtractionHandler .

Vector 3: Windows Updater — Full Arbitrary File Write + Execution

cmd/updater/updater_windows.go has two separate zip-slip bugs:

installByInstaller (line 48):

After extraction, the code searches for .exe / .msi files and EXECUTES them (line 84: exec.Command(installerPath) ). A crafted update package achieves arbitrary code execution.

installByPortable (line 104):

Writes files directly to the application's install directory with no path validation.

Both use Go's archive/zip reader directly, bypassing the extractFile function entirely.

Requires: Go 1.21+, Python 3 with py7zr ( pip3 install py7zr ), curl.

Run exploit.sh — it clones Gopeed, builds the real REST API server from source, starts it, then downloads malicious archives via the Gopeed HTTP download pipeline with AutoExtract enabled.

Vector 1 (7z arbitrary file write): Serves a .7z.001 archive with entry ../../FILE_ESCAPED/pwned.txt via HTTP. Gopeed downloads it, detects multi-part 7z, routes to extractSevenZipMultiPart which writes the file outside the download directory with zero sanitization.

Vector 2 (directory escape): Serves a tar.gz with directory entry ../../ESCAPED/ via HTTP. Gopeed downloads it, routes to extractArchive → extractFile , which processes directory entries before the path sanitization check and creates directories outside the download directory.

Vector 3 (Windows updater): Code path analysis — updater_windows.go:48,104 have zero sanitization. Requires a compromised or MITM'd update server to exploit; the updater extracts and EXECUTES the payload.

An attacker crafts a malicious archive (7z, zip, tar.gz, rar) and distributes it via any download link. When a Gopeed user downloads it with AutoExtract enabled (or manually extracts), files are written to arbitrary paths on the filesystem.

Vector 1 (7z multi-part): Arbitrary file write. Attacker can overwrite ~/.bashrc , ~/.ssh/authorized_keys , cron jobs, or application configuration. Severity: CRITICAL.

Vector 2 (directory escape): Arbitrary directory creation. Lower severity alone but enables preparation for follow-up attacks (creating .ssh/ , cron directories). Severity: MEDIUM.

Vector 3 (Windows updater): Arbitrary file write + code execution. Requires MITM or compromised update channel. Severity: CRITICAL (when reachable).

The AutoExtract feature ( pkg/protocol/http/model.go:17 ) triggers extraction automatically on download completion, making exploitation zero-click once the user clicks a download link.

For Vector 1 ( extract_7z.go ): Add path sanitization before file write, consistent with extractFile :

For Vector 2 ( extract.go:287 ): Move the sanitization check BEFORE the directory handling:

For Vector 3 ( updater_windows.go ): Add the same sanitization before each filepath.Join(tempDir/destDir, file.Name) .

Additionally, add filepath.Rel(destDir, destPath) validation to ensure the resolved path stays within destDir , which guards against symlink-based escapes.

Extracted Entities

Attack Types (1)

CWE Weaknesses (1)

Domains (1)

Platforms (1)

Tools (2)

Vulnerabilities (1)