Why this matters
The bug. Asking the OS to launch /bin/sh -c "…{userPath}…" re-introduces the shell as a parser. Any metacharacter in userPath — ;, &&, backticks, $() — gets the shell's interpretation, not the file system's. The result: arbitrary command execution under the service account.
The fix. Skip the shell. ProcessStartInfo exposes ArgumentList (or the array constructor) so the kernel hands each argument to convert directly, no string parsing in between. Arguments (the legacy single-string field) has the same problem as sh -c because Windows quoting rules require you to escape metacharacters yourself.
Heuristic. Any time you reach for /bin/sh -c from inside an application, you've crossed back into a shell-parsing context. Push the orchestration (pipes, redirection) into your own code instead.
Review heuristic
If a string built from a request flows into a function whose name involves the words shell, system, exec, popen, or eval, treat it as actively dangerous until you can show that no part of the string is attacker-controlled.
External reference: CWE-78: OS Command Injection.
↳ CWE-78: OS Command Injection.