GuardAPI Logo
GuardAPI
Automated Security Protocol

How to fix Command Injection
in Vapor (Swift)

Executive Summary

Command Injection in Vapor occurs when untrusted user input is passed directly into system execution sinks like `Process` or custom shell wrappers. When input is concatenated into a shell string, attackers use metacharacters like `;`, `&`, or `|` to break out of the intended command and execute arbitrary code with the privileges of the Swift process.

The Vulnerable Pattern

VULNERABLE CODE
app.get("lookup") { req -> String in
    let domain = req.query["domain"] ?? "google.com"
    let process = Process()
    process.executableURL = URL(fileURLWithPath: "/bin/sh")
    // VULNERABLE: String interpolation inside a shell command string
    process.arguments = ["-c", "nslookup \(domain)"]
    let pipe = Pipe()
    process.standardOutput = pipe
    try process.run()
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    return String(data: data, encoding: .utf8) ?? ""
}

The Secure Implementation

The exploit vector is the shell's command parser. By using `sh -c`, the input is interpreted for control characters. The fix involves: 1. Eliminating the shell intermediary by invoking the target binary (`/usr/bin/nslookup`) directly via `executableURL`. 2. Passing user input as separate elements in the `arguments` array. This forces the OS to treat the input as a literal string argument rather than executable code. 3. Implementing a strict allow-list regex to validate the input format before it ever reaches the system sink.

SECURE CODE
app.get("lookup") { req -> String in
    guard let domain = req.query["domain"], 
          domain.range(of: "^[a-zA-Z0-9.-]+$", options: .regularExpression) != nil else {
        throw Abort(.badRequest, reason: "Invalid domain format")
    }
    let process = Process()
    // SECURE: Call the binary directly, avoiding /bin/sh entirely
    process.executableURL = URL(fileURLWithPath: "/usr/bin/nslookup")
    // SECURE: Pass arguments as a discrete [String] array; no shell parsing occurs
    process.arguments = [domain]
    let pipe = Pipe()
    process.standardOutput = pipe
    try process.run()
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    return String(data: data, encoding: .utf8) ?? ""
}
System Alert • ID: 5428
Target: Vapor (Swift) API
Potential Vulnerability

Your Vapor (Swift) API might be exposed to Command Injection

74% of Vapor (Swift) apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

Free Tier • No Credit Card • Instant Report

Verified by Ghost Labs Security Team

This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.