flawopen.com/Command Injection/Swift

Command Injection in Swift

Critical CWE-78 Draft — pending review
ELI5

Imagine a secretary who executes whatever is written on a memo. If someone writes 'Buy stamps AND delete all company files', command injection is doing both because the memo didn't separate instructions from items.

Key terms on this page
Process (formerly NSTask)
The Foundation framework class for running subprocesses in Swift, passing arguments via the arguments array.
system()
The C standard library function available in Swift that invokes /bin/sh directly.

What's happening

In Swift CLI tools, server-side Swift (Vapor), or macOS utilities, invoking system() or passing strings to /bin/sh -c via Process causes command injection.

Real-world impact

macOS helper tools and XPC services running with root privileges have suffered local privilege escalation through unvalidated Process arguments.

Apple Security Advisories & CVE Database.

Vulnerable vs. fixed

VULNERABLE
// Calling /bin/sh with string interpolation
import Foundation

func ping(host: String) {
    // Attacker input: "127.0.0.1; whoami"
    let process = Process()
    process.executableURL = URL(fileURLWithPath: "/bin/sh")
    process.arguments = ["-c", "ping -c 1 \(host)"]
    try? process.run()
}
FIXED
// Calling binary directly with isolated arguments array
import Foundation

func ping(host: String) {
    let process = Process()
    process.executableURL = URL(fileURLWithPath: "/sbin/ping")
    // host is strictly an argument, never parsed as a shell command
    process.arguments = ["-c", "1", host]
    try? process.run()
}

Why the fix works

Setting executableURL directly to the target binary and passing parameters in the arguments array calls the operating system's posix_spawn API directly without invoking a shell.

Gotchas

system() in Swift

Importing Darwin or Glibc allows calling C's system() directly, which inherits all the vulnerabilities of C command injection.

Common misconceptions

"App Sandbox prevents all command injection"

The macOS App Sandbox restricts file and network access, but helper tools or server-side Swift applications running outside the sandbox have full system access.

How to check if you're affected

grep -rn 'process.arguments = \["-c"' --include="*.swift" . grep -rn "system(" --include="*.swift" .
Run SwiftLint and custom regex rules to forbid direct shell spawning.

Prevention checklist

FAQ

Is Process available on iOS?

No. iOS apps run in an isolated sandbox where spawning arbitrary subprocesses is restricted by the operating system.

References

View in: Python JavaScript Go Java PHP C# Ruby C/C++ Rust Kotlin Swift Solidity (N/A)
Also see: SQL Injection XSS Path Traversal Insecure Deserialization