HIGH zip slipgin

Zip Slip in Gin

How Zip Slip Manifests in Gin

Zip Slip is a directory traversal vulnerability that occurs when extracting files from archives without validating path traversal sequences. In Gin applications, this manifests through file upload endpoints that accept ZIP archives and extract them to disk.

The vulnerability allows attackers to write files outside the intended extraction directory by using path traversal sequences like ../ in filenames within the ZIP archive. For example, a file named ../../etc/passwd would overwrite the system's password file if extracted without validation.

In Gin applications, Zip Slip typically appears in file upload handlers that process ZIP archives. Consider this vulnerable pattern:

func uploadZip(c *gin.Context) {
    file, _ := c.FormFile("file")
    zipReader, _ := zip.OpenReader(file.Filename)
    defer zipReader.Close()
    
    for _, f := range zipReader.File {
        f.Open()
        f.Read()
        // No path validation - vulnerable to Zip Slip
        os.MkdirAll(filepath.Dir(f.Name), 0755)
        os.WriteFile(f.Name, content, 0644)
    }
    c.JSON(200, gin.H{"status": "uploaded"})
}

This code is vulnerable because it directly uses f.Name without validating that the path doesn't escape the intended directory. An attacker could upload a ZIP containing ../../go.mod and overwrite the application's module file.

Gin's middleware and routing structure doesn't inherently prevent Zip Slip - it's a file handling issue that occurs after the request is processed. The vulnerability is particularly dangerous in Gin applications because:

  • Gin's file upload handling makes it easy to accept arbitrary files
  • The framework doesn't provide built-in ZIP extraction with path validation
  • Gin's simplicity can lead developers to implement extraction logic without security considerations
  • Production Gin applications often run with elevated privileges, increasing the impact

Attackers can exploit this by creating ZIP archives with malicious path sequences, uploading them to the vulnerable endpoint, and having the server extract files to arbitrary locations, potentially overwriting critical files or placing executable code in sensitive directories.

Gin-Specific Detection

Detecting Zip Slip vulnerabilities in Gin applications requires both static analysis and runtime scanning. For static analysis, look for patterns where ZIP files are extracted without path validation:

// Vulnerable patterns to search for:
zip.OpenReader()
archive/zip
filepath.Join() with user-controlled input
os.MkdirAll() with user-controlled paths
os.WriteFile() with user-controlled paths

middleBrick's API security scanner can detect Zip Slip vulnerabilities in your Gin applications by scanning running endpoints. The scanner tests file upload functionality by submitting ZIP archives containing path traversal sequences and verifies if files are written outside the intended directory.

middleBrick specifically tests for:

  • Authentication bypass in file upload endpoints
  • Path traversal in extracted file names
  • Permission escalation through arbitrary file writes
  • Property authorization violations in file handling
  • Input validation failures in file upload processing

The scanner creates test ZIP archives with filenames like test/../../test_output/success and verifies that extraction is properly sandboxed. If the scanner can write files outside the intended directory, it flags a critical Zip Slip vulnerability.

For manual testing, you can use the following approach:

# Create a test ZIP with path traversal
zip -r test.zip "test/../../test_output/success"

# Upload to your Gin endpoint
curl -X POST -F "[email protected]" http://localhost:8080/upload

After extraction, check if the test_output/success file was created in the intended directory or if it escaped to an unexpected location. middleBrick automates this process and provides detailed reports with the exact paths that were successfully traversed.

The scanner also checks for related issues like insufficient file type validation, which could allow executable files to be uploaded and extracted to sensitive locations, and missing rate limiting on file upload endpoints.

Gin-Specific Remediation

Remediating Zip Slip in Gin applications requires implementing proper path validation before extracting files. The most effective approach is to validate each file's path against the intended extraction directory:

import (
    "archive/zip"
    "path/filepath"
    "strings"
)

func safeExtractZip(c *gin.Context, targetDir string) error {
    file, err := c.FormFile("file")
    if err != nil {
        return err
    }
    
    zipReader, err := zip.OpenReader(file.Filename)
    if err != nil {
        return err
    }
    defer zipReader.Close()
    
    for _, f := range zipReader.File {
        // Clean and validate the path
        safePath := filepath.Join(targetDir, f.Name)
        safePath = filepath.Clean(safePath)
        
        // Ensure the cleaned path is still within the target directory
        if !strings.HasPrefix(safePath, filepath.Clean(targetDir)+string(filepath.Separator)) {
            return errors.New("path traversal detected")
        }
        
        if f.FileInfo().IsDir() {
            os.MkdirAll(safePath, 0755)
        } else {
            rc, err := f.Open()
            if err != nil {
                return err
            }
            defer rc.Close()
            
            content, err := io.ReadAll(rc)
            if err != nil {
                return err
            }
            
            if err := os.WriteFile(safePath, content, f.Mode()); err != nil {
                return err
            }
        }
    }
    return nil
}

This remediation ensures that after cleaning the path, it still starts with the intended target directory. The filepath.Clean function normalizes the path, and the prefix check prevents traversal outside the allowed directory.

For additional security in Gin applications, implement these best practices:

func uploadZipSecure(c *gin.Context) {
    // Validate file type and size
    file, err := c.FormFile("file")
    if err != nil || !strings.HasSuffix(file.Filename, ".zip") {
        c.JSON(400, gin.H{"error": "invalid file"})
        return
    }
    
    // Limit file size to prevent DoS
    if file.Size > 10*1024*1024 { // 10MB limit
        c.JSON(400, gin.H{"error": "file too large"})
        return
    }
    
    // Extract to a safe directory
    targetDir := "./uploads/"
    if err := safeExtractZip(c, targetDir); err != nil {
        c.JSON(500, gin.H{"error": "extraction failed", "details": err.Error()})
        return
    }
    
    c.JSON(200, gin.H{"status": "uploaded securely"})
}

middleBrick's continuous monitoring can verify that your remediation remains effective over time. The Pro plan includes scheduled scans that test your API endpoints with updated attack patterns, ensuring new Zip Slip variants are detected.

For production deployments, consider these additional security layers:

  • Run the application with minimal privileges to limit the impact of successful exploitation
  • Store uploaded files on a separate filesystem with strict permissions
  • Implement file type validation to reject unexpected file formats
  • Use a dedicated file processing service that runs in a sandboxed environment
  • Monitor file system changes for suspicious activity

middleBrick's GitHub Action integration can automatically scan your API endpoints in CI/CD pipelines, failing builds if Zip Slip vulnerabilities are detected in new code. This ensures that security regressions are caught before deployment.

Frequently Asked Questions

How can I test if my Gin application is vulnerable to Zip Slip?
Create a ZIP archive with files containing path traversal sequences like ../../test.txt, upload it to your Gin file upload endpoint, and verify if files are written outside the intended directory. middleBrick automates this testing by submitting crafted ZIP archives and checking for path traversal success.
Does Gin provide any built-in protection against Zip Slip?
No, Gin doesn't provide built-in protection against Zip Slip. It's a file handling vulnerability that occurs in application logic after Gin processes the HTTP request. You need to implement path validation in your own code when extracting ZIP archives.