HIGH command injectionfiber

Command Injection in Fiber

How Command Injection Manifests in Fiber

Command injection vulnerabilities in Fiber applications typically arise when user input is incorporated into system commands without proper sanitization. Fiber's Go-based architecture means these vulnerabilities often appear in handler functions that execute external processes or shell commands based on HTTP request parameters.

A common pattern involves using os/exec with exec.Command where user input is concatenated into command strings. For example:

func getFileHandler(c *fiber.Ctx) error {
    filename := c.Query("file")
    cmd := exec.Command("cat", filename)
    output, err := cmd.Output()
    if err != nil {
        return c.Status(500).SendString(err.Error())
    }
    return c.SendString(string(output))
}

This code is vulnerable because an attacker can supply a filename like file.txt; rm -rf /, causing the shell to execute multiple commands. The vulnerability becomes more severe when combined with Fiber's middleware ecosystem, where request parameters might flow through multiple processing layers before reaching command execution logic.

Another Fiber-specific scenario involves using user input in exec.CommandContext with shell expansion. Consider this handler:

func searchHandler(c *fiber.Ctx) error {
    query := c.Query("q")
    cmd := exec.Command("grep", "-r", query, "/var/www")
    output, err := cmd.Output()
    if err != nil {
        return c.Status(500).SendString(err.Error())
    }
    return c.SendString(string(output))
}

While this appears safe, if query contains special characters like $(whoami) or backticks, they can be interpreted by the shell in certain execution contexts, especially if the command is later modified or if the Go runtime's command execution behavior changes.

Property authorization bypasses in Fiber can also lead to command injection when user input controls file paths or command arguments. A vulnerable pattern might look like:

func adminAction(c *fiber.Ctx) error {
    action := c.Query("action")
    if action == "backup" {
        cmd := exec.Command("tar", "-czf", "/backups/"+c.Query("filename"), "/var/www")
        return cmd.Run()
    }
    return c.Status(400).SendString("Invalid action")
}

Here, an attacker could manipulate the filename parameter to include directory traversal or command injection payloads, potentially overwriting critical files or executing arbitrary commands.

Fiber-Specific Detection

Detecting command injection in Fiber applications requires both static code analysis and dynamic runtime testing. middleBrick's black-box scanning approach is particularly effective for Fiber APIs because it tests the actual runtime behavior without requiring source code access.

middleBrick scans Fiber applications by sending crafted payloads to endpoints that might execute system commands. For command injection detection, it tests parameters with payloads like:

; echo 'injection'
$(whoami)
`id`
& cat /etc/passwd
| ls -la

The scanner analyzes responses for indicators of successful injection, such as unexpected output, timing differences, or error messages that reveal system information. middleBrick's 12 parallel security checks include specific tests for command injection patterns, examining both GET and POST parameters, headers, and even JSON payloads.

For Fiber applications using middleware chains, middleBrick's scanning simulates real-world attack scenarios where user input flows through multiple processing stages. This is crucial because command injection vulnerabilities might only manifest when certain middleware modifies or validates input in specific ways.

middleBrick's OpenAPI/Swagger analysis adds another layer of detection for Fiber apps. By analyzing the API specification alongside runtime scanning, it can identify endpoints that accept parameters likely to be used in command execution contexts. The scanner cross-references parameter definitions with actual runtime behavior to find mismatches between documented and implemented security controls.

LLM/AI security scanning is particularly relevant for Fiber applications using AI features. middleBrick tests for system prompt leakage and prompt injection that could lead to command execution through AI agents or tools. This includes testing for patterns like:

"system": "Execute: whoami",
"role": "user", "content": "run: ls -la"

middleBrick's scanning takes 5-15 seconds and provides a security score (0-100) with letter grades (A-F), making it easy to identify command injection vulnerabilities in Fiber applications during development or in production environments.

Fiber-Specific Remediation

Remediating command injection in Fiber applications requires a defense-in-depth approach using Go's native security features. The most fundamental fix is avoiding shell command execution entirely when possible. For file operations that might tempt developers to use shell commands, use Go's native file I/O instead:

func readFileHandler(c *fiber.Ctx) error {
    filename := c.Query("file")
    
    // Validate filename - allow only alphanumeric, hyphen, underscore, dot
    if matched, _ := regexp.MatchString(`^[a-zA-Z0-9._-]+$`, filename); !matched {
        return c.Status(400).SendString("Invalid filename")
    }
    
    // Use absolute path with safe directory
    safeDir := "/var/www/files"
    filePath := path.Join(safeDir, filename)
    
    // Ensure path is within safeDir
    if !strings.HasPrefix(filePath, safeDir) {
        return c.Status(400).SendString("Invalid path")
    }
    
    data, err := os.ReadFile(filePath)
    if err != nil {
        return c.Status(404).SendString("File not found")
    }
    
    return c.Send(data)
}

When shell commands are unavoidable, use exec.Command with individual arguments instead of building command strings:

func safeCommand(c *fiber.Ctx) error {
    cmdName := c.Query("cmd")
    cmdArg := c.Query("arg")
    
    // Whitelist allowed commands
    allowedCommands := map[string]bool{
        "ls": true,
        "cat": true,
        "grep": true,
    }
    
    if !allowedCommands[cmdName] {
        return c.Status(400).SendString("Command not allowed")
    }
    
    // Validate arguments - allow only safe characters
    if matched, _ := regexp.MatchString(`^[a-zA-Z0-9._/-]+$`, cmdArg); !matched {
        return c.Status(400).SendString("Invalid argument")
    }
    
    cmd := exec.Command(cmdName, cmdArg)
    output, err := cmd.Output()
    if err != nil {
        return c.Status(500).SendString(err.Error())
    }
    
    return c.SendString(string(output))
}

For Fiber applications with complex input validation needs, implement a validation middleware:

func validationMiddleware() fiber.Handler {
    return func(c *fiber.Ctx) error {
        // Check for suspicious patterns
        suspiciousPatterns := []string{
            "$(",
            "`",
            ";",
            "&",
            "|",
            "&&",
            "||",
        }
        
        for _, pattern := range suspiciousPatterns {
            if strings.Contains(c.OriginalURL(), pattern) {
                return c.Status(400).SendString("Suspicious input detected")
            }
        }
        
        return c.Next()
    }
}

// Use in app setup
app := fiber.New()
app.Use(validationMiddleware())

Additionally, implement proper error handling to avoid information disclosure:

func executeWithTimeout(c *fiber.Ctx) error {
    cmd := exec.Command("somecommand", c.Query("param"))
    
    // Set timeout to prevent resource exhaustion
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
    cmd = cmd.WithContext(ctx)
    
    var output bytes.Buffer
    cmd.Stdout = &output
    cmd.Stderr = &output
    
    err := cmd.Run()
    if err != nil {
        // Log error internally, don't expose system details
        log.Printf("Command execution failed: %v", err)
        return c.Status(500).SendString("Command execution failed")
    }
    
    return c.SendString(output.String())
}

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

How can I test my Fiber application for command injection vulnerabilities?
Use middleBrick's black-box scanning by submitting your API endpoint URL. It tests for command injection by sending payloads like $(whoami), `id`, and ; echo injection to parameters, then analyzes responses for successful exploitation indicators. The scan takes 5-15 seconds and provides a security score with specific findings and remediation guidance.
What's the difference between using exec.Command and exec.CommandContext in Fiber applications?
exec.CommandContext adds timeout and cancellation capabilities through Go's context package. This is crucial for preventing resource exhaustion attacks where an attacker could cause your Fiber application to hang indefinitely. Always use exec.CommandContext with appropriate timeouts (typically 5-30 seconds) for any external command execution in production Fiber applications.