HIGH symlink attackfiber

Symlink Attack in Fiber

How Symlink Attack Manifests in Fiber

Symlink attacks in Fiber applications typically exploit the framework's file handling capabilities, particularly when serving user-uploaded content or processing file paths. These attacks occur when an attacker creates symbolic links that point to sensitive files or directories outside the intended scope.

In Fiber, symlink attacks often manifest through path traversal vulnerabilities combined with symbolic link resolution. For example, when Fiber serves files using c.Context().SendFile() or similar methods, an attacker might upload a malicious symlink that points to /etc/passwd or other sensitive system files.

A common Fiber-specific scenario involves file upload endpoints. Consider this vulnerable pattern:

func uploadFile(c *fiber.Ctx) error {
    file, err := c.FormFile("file")
    if err != nil {
        return err
    }
    
    // Vulnerable: no symlink check
    c.SaveFile(file, fmt.Sprintf("./uploads/%s", file.Filename))
    return c.JSON(fiber.Map{"message": "success"})
}

An attacker could upload a file named ../../../../etc/passwd or create a symlink that resolves to sensitive system files. Fiber's default file handling doesn't automatically resolve symlinks, but when combined with other filesystem operations, this can lead to information disclosure.

Another manifestation occurs in API endpoints that process file paths dynamically. For instance:

func getFile(c *fiber.Ctx) error {
    filePath := c.Params("path")
    
    // Vulnerable: no path validation
    return c.SendFile(filePath)
}

Here, an attacker could request /api/files/../../../etc/passwd, potentially accessing files outside the intended directory. While Fiber's SendFile method has some built-in protections, improper validation can still lead to symlink-based attacks.

Symlink attacks in Fiber are particularly dangerous when combined with race conditions. An attacker might create a symlink, trigger the vulnerable endpoint, and then quickly replace the symlink target before the application reads it. This time-of-check-to-time-of-use (TOCTOU) vulnerability can bypass simple existence checks.

Fiber-Specific Detection

Detecting symlink attacks in Fiber applications requires both static code analysis and runtime monitoring. For static detection, middleBrick's API security scanner specifically checks for vulnerable file handling patterns in Fiber applications.

middleBrick scans Fiber endpoints by analyzing the runtime behavior of file-serving endpoints. It tests for symlink vulnerabilities by attempting to access files through path traversal sequences like ../../ and checking if the application resolves these to sensitive files. The scanner also tests for race conditions by creating temporary symlinks and monitoring how the application handles them.

Key detection patterns middleBrick looks for in Fiber applications:

  • Endpoints using c.SendFile() or c.SaveFile() without proper path validation
  • File upload handlers that don't check for symlink creation
  • Dynamic path resolution based on user input
  • Missing filepath.Clean() or similar sanitization
  • Race condition vulnerabilities in file operations

For manual detection, you can implement runtime checks in your Fiber application:

func safeSendFile(c *fiber.Ctx, filePath string) error {
    // Resolve symlinks and check if path is within allowed directory
    realPath, err := filepath.Abs(filePath)
    if err != nil {
        return c.Status(400).JSON(fiber.Map{"error": "invalid path"})
    }
    
    // Define allowed directory
    allowedDir, _ := filepath.Abs("./uploads/")
    
    // Check if resolved path is within allowed directory
    if !strings.HasPrefix(realPath, allowedDir) {
        return c.Status(403).JSON(fiber.Map{"error": "access denied"})
    }
    
    return c.SendFile(realPath)
}

middleBrick's continuous monitoring (available in Pro plan) can automatically detect when new symlink vulnerabilities are introduced in your Fiber codebase by scanning your API endpoints on a configurable schedule and alerting you to any regression in security posture.

Fiber-Specific Remediation

Remediating symlink attacks in Fiber requires a defense-in-depth approach. Here are Fiber-specific fixes for common vulnerability patterns:

For file upload endpoints, implement strict filename validation and symlink detection:

func secureUpload(c *fiber.Ctx) error {
    file, err := c.FormFile("file")
    if err != nil {
        return c.Status(400).JSON(fiber.Map{"error": "invalid file"})
    }
    
    // Validate filename - no path traversal characters
    if strings.Contains(file.Filename, "..") || strings.Contains(file.Filename, "/") {
        return c.Status(400).JSON(fiber.Map{"error": "invalid filename"})
    }
    
    // Save to uploads directory with clean path
    uploadPath := filepath.Join("./uploads", file.Filename)
    
    // Check if file is a symlink before saving
    if isSymlink(uploadPath) {
        return c.Status(400).JSON(fiber.Map{"error": "symlink not allowed"})
    }
    
    c.SaveFile(file, uploadPath)
    return c.JSON(fiber.Map{"message": "upload successful"})
}

func isSymlink(path string) bool {
    fileInfo, err := os.Lstat(path)
    if err != nil {
        return false
    }
    return fileInfo.Mode()&os.ModeSymlink != 0
}

For dynamic file serving, use Fiber's built-in path validation and add additional checks:

func secureServeFile(c *fiber.Ctx) error {
    filePath := c.Params("path")
    
    // Clean the path to prevent traversal
    cleanPath := filepath.Clean(filePath)
    
    // Resolve to absolute path within uploads directory
    baseDir := filepath.Clean("./uploads")
    targetPath := filepath.Join(baseDir, cleanPath)
    
    // Verify the resolved path is within the base directory
    if !strings.HasPrefix(targetPath, baseDir+string(filepath.Separator)) {
        return c.Status(403).JSON(fiber.Map{"error": "forbidden"})
    }
    
    // Check if target is a symlink
    if isSymlink(targetPath) {
        return c.Status(403).JSON(fiber.Map{"error": "symlink not allowed"})
    }
    
    return c.SendFile(targetPath)
}

For race condition protection, use atomic file operations and validate file integrity:

func atomicFileOperation(c *fiber.Ctx) error {
    tempFile, err := os.CreateTemp("./uploads", "temp_*.dat")
    if err != nil {
        return err
    }
    defer os.Remove(tempFile.Name())
    
    // Write data to temp file
    _, err = tempFile.Write([]byte("sensitive data"))
    if err != nil {
        return err
    }
    tempFile.Close()
    
    // Atomic rename - prevents symlink replacement during operation
    finalPath := filepath.Join("./uploads", "final.dat")
    err = os.Rename(tempFile.Name(), finalPath)
    if err != nil {
        return err
    }
    
    // Verify file integrity after operation
    if isSymlink(finalPath) {
        os.Remove(finalPath)
        return c.Status(500).JSON(fiber.Map{"error": "file integrity compromised"})
    }
    
    return c.JSON(fiber.Map{"message": "operation completed"})
}

middleBrick's GitHub Action can automatically scan your Fiber application during CI/CD pipelines, ensuring these remediation patterns are consistently applied across your codebase and preventing symlink vulnerabilities from reaching production.

Frequently Asked Questions

How does middleBrick specifically detect symlink attacks in Fiber applications?
middleBrick uses black-box scanning to test Fiber endpoints by sending requests with path traversal sequences and symlink patterns. It attempts to access files outside the intended directory structure and monitors the application's response to identify symlink resolution vulnerabilities. The scanner also tests for race conditions by creating temporary symlinks and observing how the Fiber application handles them during file operations.
Can middleBrick scan my Fiber application during development?
Yes, middleBrick offers multiple scanning options for Fiber development. You can use the CLI tool to scan your local development server with 'middlebrick scan http://localhost:3000', integrate the GitHub Action into your CI/CD pipeline to scan staging APIs before deployment, or use the MCP Server to scan APIs directly from your IDE while coding. The Free plan includes 3 scans per month, perfect for trying it out during development.