HIGH zip slipfiber

Zip Slip in Fiber

How Zip Slip Manifests in Fiber

Zip Slip is a path traversal vulnerability that occurs when an application extracts files from a ZIP archive without validating the file paths within the archive. In Fiber applications, this manifests through several specific patterns that developers should be aware of.

The most common Fiber-specific manifestation occurs in file upload handlers where users can submit ZIP archives. Consider this vulnerable pattern:

func uploadZip(c *fiber.Ctx) error {
    // Parse the multipart form
    err := c.BodyParser(&payload)
    if err != nil { return err }

    // Read the uploaded file
    file, err := c.FormFile("file")
    if err != nil { return err }

    // Save to disk
    src, err := file.Open()
    if err != nil { return err }
    defer src.Close()

    // Create a zip reader
    zipReader, err := zip.NewReader(src, file.Size)
    if err != nil { return err }

    // Extract all files without validation
    for _, f := range zipReader.File {
        rc, err := f.Open()
        if err != nil { return err }
        defer rc.Close()

        // Create target path
        targetPath := filepath.Join("./uploads", f.Name)
        
        // Write file to disk
        out, err := os.Create(targetPath)
        if err != nil { return err }
        defer out.Close()

        io.Copy(out, rc)
    }

    return c.JSON(fiber.Map{"message": "Files extracted successfully"})
}

The critical vulnerability here is filepath.Join("./uploads", f.Name). If an attacker includes a file named ../../etc/passwd in their ZIP archive, the filepath.Join function will resolve this to a path outside the intended upload directory, potentially overwriting system files or accessing sensitive data.

Another Fiber-specific pattern involves middleware that handles file processing:

func FileProcessorMiddleware(next fiber.Handler) fiber.Handler {
    return func(c *fiber.Ctx) error {
        // Check if file was uploaded
        if c.Get("Content-Type") == "application/zip" {
            // Extract and process ZIP
            file, err := c.FormFile("archive")
            if err != nil { return err }

            // Dangerous extraction without validation
            extractZip(file)
        }
        return next(c)
    }
}

Attackers can craft ZIP archives with files like ../config.json, ../../secret.key, or even ../../../../../../etc/passwd to traverse directory structures and overwrite critical files.

Fiber-Specific Detection

Detecting Zip Slip vulnerabilities in Fiber applications requires both manual code review and automated scanning. Here are Fiber-specific detection methods:

Manual Code Review Patterns

Look for these specific patterns in your Fiber codebase:

# Search for dangerous patterns
grep -r "zip\.NewReader" . --include="*.go"
grep -r "filepath\.Join" . --include="*.go" | grep -E "(\.Name|filename)"
grep -r "os\.Create" . --include="*.go" | grep -E "(\.Name|filename)"

Focus on handlers that accept file uploads and process ZIP archives. The vulnerable pattern typically involves:

  1. Accepting multipart form data with c.FormFile()
  2. Creating a zip.NewReader from the uploaded file
  3. Iterating through zipReader.File without path validation
  4. Using filepath.Join with user-controlled filenames

middleBrick Security Scanning

middleBrick provides Fiber-specific Zip Slip detection through its black-box scanning approach. Unlike source code analysis tools, middleBrick tests the actual running API endpoints:

# Scan your Fiber API with middleBrick
middlebrick scan https://yourapi.com/upload-zip

middleBrick tests for Zip Slip by:

  • Submitting crafted ZIP archives with traversal paths
  • Verifying if extracted files appear outside the intended directory
  • Checking for successful path traversal attempts
  • Mapping findings to OWASP API Top 10 (A1: Injection, A4: Path Traversal)
  • The scanner provides a security score with specific findings like:

    {
      "severity": "high",
      "category": "Path Traversal",
      "finding": "Zip Slip vulnerability in /api/upload-zip endpoint",
      "remediation": "Validate file paths before extraction and sanitize filenames",
      "cve_reference": "CVE-2018-1000533"
    }

    Static Analysis with golangci-lint

    Configure golangci-lint to catch potential Zip Slip patterns:

    # .golangci.yml
    linters:
      enable:
        - gosec
        - staticcheck
    
    run:
      skip-dirs:
        - vendor
        - node_modules
    
    issues:
      exclude-use-default: false
    

    Add custom checks for dangerous patterns or use security-focused linters that can detect path traversal vulnerabilities.

Fiber-Specific Remediation

Remediating Zip Slip vulnerabilities in Fiber applications requires implementing proper path validation and secure file handling practices. Here are Fiber-specific solutions:

Path Validation Before Extraction

The most critical fix is validating file paths before extraction:

import (
    "path/filepath"
    "strings"
    "github.com/gofiber/fiber"
)

func validateZipPath(baseDir, zipPath string) (string, error) {
    // Clean and normalize the path
    cleanPath := filepath.Clean(zipPath)
    
    // Check for path traversal
    if strings.Contains(cleanPath, "..") {
        return "", fiber.NewError(fiber.StatusBadRequest, "Invalid file path")
    }
    
    // Ensure path is within base directory
    targetPath := filepath.Join(baseDir, cleanPath)
    if !strings.HasPrefix(targetPath, filepath.Clean(baseDir)) {
        return "", fiber.NewError(fiber.StatusBadRequest, "Path traversal detected")
    }
    
    return targetPath, nil
}

func secureUploadZip(c *fiber.Ctx) error {
    file, err := c.FormFile("file")
    if err != nil { return err }

    src, err := file.Open()
    if err != nil { return err }
    defer src.Close()

    zipReader, err := zip.NewReader(src, file.Size)
    if err != nil { return err }

    baseDir := "./secure-uploads"
    os.MkdirAll(baseDir, 0755)

    for _, f := range zipReader.File {
        targetPath, err := validateZipPath(baseDir, f.Name)
        if err != nil {
            return err
        }

        // Create directories if needed
        os.MkdirAll(filepath.Dir(targetPath), 0755)

        rc, err := f.Open()
        if err != nil { return err }
        defer rc.Close()

        out, err := os.Create(targetPath)
        if err != nil { return err }
        defer out.Close()

        io.Copy(out, rc)
    }

    return c.JSON(fiber.Map{"message": "Files extracted securely"})
}

Filename Sanitization

Sanitize filenames to prevent malicious path components:

func sanitizeFilename(name string) string {
    // Remove path traversal patterns
    clean := filepath.Clean(name)
    
    // Remove any remaining dangerous characters
    clean = strings.ReplaceAll(clean, "../", "")
    clean = strings.ReplaceAll(clean, "..\\", "")
    
    // Only allow alphanumeric, dash, underscore, dot
    var allowed []rune
    for _, r := range clean {
        if (r >= 'a' && r <= 'z') || 
            (r >= 'A' && r <= 'Z') || 
            (r >= '0' && r <= '9') || 
            r == '-' || r == '_' || r == '.' || r == '/' {
            allowed = append(allowed, r)
        }
    }
    
    return string(allowed)
}

func uploadWithSanitization(c *fiber.Ctx) error {
    file, err := c.FormFile("archive")
    if err != nil { return err }

    src, err := file.Open()
    if err != nil { return err }
    defer src.Close()

    zipReader, err := zip.NewReader(src, file.Size)
    if err != nil { return err }

    baseDir := "./sanitized-uploads"
    os.MkdirAll(baseDir, 0755)

    for _, f := range zipReader.File {
        sanitizedName := sanitizeFilename(f.Name)
        targetPath := filepath.Join(baseDir, sanitizedName)
        
        // Additional validation
        if !strings.HasPrefix(targetPath, filepath.Clean(baseDir)) {
            return fiber.NewError(fiber.StatusBadRequest, "Invalid filename")
        }

        rc, err := f.Open()
        if err != nil { return err }
        defer rc.Close()

        out, err := os.Create(targetPath)
        if err != nil { return err }
        defer out.Close()

        io.Copy(out, rc)
    }

    return c.JSON(fiber.Map{"message": "Files extracted with sanitization"})
}

Using Temporary Directories

Isolate extracted files in temporary directories:

import (
    "io/ioutil"
    "os"
    "github.com/gofiber/fiber"
)

func extractToTemp(c *fiber.Ctx) error {
    file, err := c.FormFile("file")
    if err != nil { return err }

    src, err := file.Open()
    if err != nil { return err }
    defer src.Close()

    // Create a unique temporary directory
    tempDir, err := ioutil.TempDir("", "fiber-upload-*")
    if err != nil { return err }
    defer os.RemoveAll(tempDir)

    zipReader, err := zip.NewReader(src, file.Size)
    if err != nil { return err }

    for _, f := range zipReader.File {
        // Clean and validate path
        cleanName := filepath.Clean(f.Name)
        if strings.Contains(cleanName, "..") {
            return fiber.NewError(fiber.StatusBadRequest, "Invalid file path")
        }

        targetPath := filepath.Join(tempDir, cleanName)
        
        // Create directories
        os.MkdirAll(filepath.Dir(targetPath), 0755)

        rc, err := f.Open()
        if err != nil { return err }
        defer rc.Close()

        out, err := os.Create(targetPath)
        if err != nil { return err }
        defer out.Close()

        io.Copy(out, rc)
    }

    // Process files from tempDir
    return c.JSON(fiber.Map{"message": "Files extracted to temp directory"})
}

Integration with middleBrick

After implementing these fixes, verify your remediation with middleBrick:

# Run middleBrick scan after fixes
middlebrick scan https://yourapi.com/upload-zip --fail-on-high-risk

# Check the report for Zip Slip findings
middlebrick report last --format=json | jq '.findings[] | select(.category == "Path Traversal")'

middleBrick's continuous monitoring (Pro plan) can automatically scan your API endpoints on a schedule, ensuring that Zip Slip vulnerabilities don't reappear as your codebase evolves.

Frequently Asked Questions

How can I test if my Fiber API is vulnerable to Zip Slip?
Create a ZIP archive containing files with traversal paths like ../../test.txt or ../../../../etc/passwd. Upload it to your Fiber endpoint and check if the files are extracted outside the intended directory. You can also use middleBrick's automated scanning which specifically tests for Zip Slip vulnerabilities by submitting crafted ZIP archives and verifying path traversal attempts.
Does middleBrick detect Zip Slip vulnerabilities in Fiber applications?
Yes, middleBrick detects Zip Slip vulnerabilities through black-box scanning. It tests your running Fiber API endpoints by submitting ZIP archives with crafted traversal paths and verifies if path traversal is possible. The scanner provides a security score, specific findings with severity levels, and remediation guidance mapped to OWASP API Top 10 categories.