Zip Slip in Fiber with Basic Auth
Zip Slip in Fiber with Basic Auth — how this specific combination creates or exposes the vulnerability
Zip Slip is a path traversal vulnerability that occurs when an application constructs file paths by directly concatenating user-supplied input with a base directory. In the Fiber web framework for Go, this commonly manifests when a handler uses unchecked user input to build filesystem paths, allowing an attacker to traverse directories using sequences like ../../. When Basic Auth is used, the presence of authentication can create a false sense of security, leading developers to assume that authenticated endpoints are less likely to be exposed or tested. However, Zip Slip depends on path manipulation, not authentication, so the vulnerability remains exploitable regardless of whether Basic Auth is enforced. An authenticated endpoint that accepts a filename or directory name as a parameter and uses it to read or extract files can still be abused if input validation is missing. The combination does not introduce the flaw, but it can obscure the risk during security scans that focus on authentication coverage rather than path traversal testing. middleBrick scans the unauthenticated attack surface by default, but its Authentication check can detect whether endpoints are properly guarded; when Basic Auth is present yet path handling is unsafe, findings will highlight missing input validation and authorization controls. Because Zip Slip can allow reading arbitrary files or writing outside the intended directory, it maps to OWASP API Top 10 A05:2023 and can contribute to a high severity risk score when discovered. Real-world examples include archive extraction libraries that do not sanitize member paths, enabling attackers to overwrite critical files via specially crafted archives.
Basic Auth-Specific Remediation in Fiber — concrete code fixes
To remediate Zip Slip in Fiber while using Basic Auth, you must validate and sanitize all user-controlled path segments before using them in filesystem operations. Do not rely on authentication to prevent traversal; enforce strict path checks and use Go’s built-in path cleaning functions. Below are concrete code examples showing insecure and secure patterns.
Insecure Fiber handler with Basic Auth and Zip Slip risk
package main
import (
"archive/zip"
"fmt"
"net/http"
"path/filepath"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/basicauth"
)
func main() {
app := fiber.New()
// Basic Auth middleware applied globally
middleware := basicauth.New(basicauth.Config{
Users: map[string]string{
"admin": "securepassword",
},
})
app.Use(middleware)
// Vulnerable endpoint: extracts user-supplied filename from query param
app.Get("/download", func(c *fiber.Ctx) error {
name := c.Query("file", "default.txt")
filepath := fmt.Sprintf("./uploads/%s", name)
f, err := os.Open(filepath)
if err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
defer f.Close()
// Unsafe zip extraction: no path sanitization
z, _ := zip.OpenReader(filepath)
for _, f := range z.File {
f.FileInfo().Open()
// Risk: path traversal via filename in zip
f.Unzip()
}
return c.SendString("Extracted")
})
app.Listen(":3000")
}
Secure Fiber handler with path sanitization
package main
import (
"archive/zip"
"fmt"
"net/http"
"path/filepath"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/basicauth"
)
func main() {
app := fiber.New()
middleware := basicauth.New(basicauth.Config{
Users: map[string]string{
"admin": "securepassword",
},
})
app.Use(middleware)
// Secure endpoint: clean and validate user input
app.Get("/download", func(c *fiber.Ctx) error {
name := c.Query("file", "default.txt")
if !isValidFilename(name) {
return c.Status(fiber.StatusBadRequest).SendString("invalid filename")
}
base := "./uploads"
cleanName := filepath.Clean(name)
// Ensure the resolved path stays within base
filepath := filepath.Join(base, cleanName)
if !strings.HasPrefix(filepath, filepath.Clean(base)+string(filepath.Separator)) && filepath != filepath.Clean(base) {
return c.Status(fiber.StatusForbidden).SendString("path traversal attempt")
}
f, err := os.Open(filepath)
if err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
defer f.Close()
// Safe extraction: sanitize each file in archive
z, err := zip.OpenReader(filepath)
if err != nil {
return c.SendStatus(fiber.StatusInternalServerError)
}
defer z.Close()
for _, file := range z.File {
if !isValidZipPath(file.Name) {
continue // skip unsafe entries
}
rc, err := file.Open()
if err != nil {
continue
}
defer rc.Close()
// Extract to a safe location
extractedPath := filepath.Join("./extracted", filepath.Base(file.Name)) // simplified example
// os.MkdirAll(filepath.Dir(extractedPath), 0755) would be used in production
// io.Copy on extracted file omitted for brevity
}
return c.SendString("Extracted safely")
})
app.Listen(":3000")
}
func isValidFilename(name string) bool {
// Allow alphanumeric, dash, underscore, and a single dot for extension
matched := regexp.MustCompile(`^[a-zA-Z0-9._-]+$`).MatchString
return matched(name) && !strings.Contains(name, "..") && !strings.HasPrefix(name, ".")
}
func isValidZipPath(path string) bool {
clean := filepath.Clean("/" + path)
return !strings.HasPrefix(clean, "..") && !strings.Contains(clean, "..")
}
These examples demonstrate that Basic Auth protects the endpoint from unauthenticated access but does not mitigate Zip Slip. Secure handling requires validating the filename format, using filepath.Clean, ensuring the resolved path remains within the intended base directory, and sanitizing entries when processing archives. middleBrick’s Authentication check confirms the presence of Basic Auth, while its Input Validation findings can highlight missing path sanitization, helping you address the flaw regardless of authentication.