flawopen.com/Command Injection/C#

Command Injection in C#

Critical CWE-78 Draft — pending review
ELI5

Imagine a secretary who runs errands. If an untrusted visitor hands the secretary a memo saying 'Deliver mail AND transfer bank funds', command injection is the secretary executing both without questioning the paper.

Key terms on this page
ProcessStartInfo.ArgumentList
.NET Core API property that passes command line arguments as a List<string> without invoking a command shell.
Arguments string concatenation
The legacy .NET property where arguments were concatenated into a single string, requiring manual escaping.

What's happening

In .NET, launching external tools using System.Diagnostics.Process with concatenated strings assigned to ProcessStartInfo.Arguments causes command injection when user input contains shell delimiters.

Real-world impact

Critical vulnerabilities in Windows desktop applications and ASP.NET management portals have resulted in full SYSTEM privilege escalation via unquoted command paths and argument injection.

Microsoft Security Response Center (MSRC) advisories.

Vulnerable vs. fixed

VULNERABLE
// Concatenating into Arguments string
var psi = new ProcessStartInfo
{
    FileName = "cmd.exe",
    // Attacker input: "test.txt & net user /add evil Password123!"
    Arguments = $"/c type {userInput}",
    RedirectStandardOutput = true
};
Process.Start(psi);
FIXED
// Using ArgumentList (.NET Core / .NET 5+) without shell
var psi = new ProcessStartInfo
{
    FileName = "notepad.exe"
};
// Arguments added individually to ArgumentList are never parsed as shell commands
psi.ArgumentList.Add(userInput);
Process.Start(psi);

Why the fix works

In .NET Core, ArgumentList properly escapes each argument according to the Win32 / POSIX command-line conventions before passing it to the operating system's CreateProcess API.

Gotchas

cmd.exe /c re-introduces command injection

If FileName is set to cmd.exe, Windows will parse the arguments using its command shell rules regardless of whether you use ArgumentList.

Common misconceptions

"Windows does not use shells like Bash, so it is safe"

Windows cmd.exe and powershell.exe support command chaining with &, &&, and | just like Linux shells.

How to check if you're affected

grep -rn "ProcessStartInfo.*Arguments\s*=" --include="*.cs" .
Enable Roslyn security analyzer rule CA3006 (Review code for process command injection vulnerabilities).

Prevention checklist

FAQ

How do I pass arguments safely in older .NET Framework (pre-Core)?

You must manually escape quotes with backslashes according to the Win32 CommandLineToArgvW rules, or upgrade to .NET 6/8+ to use ArgumentList.

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