FlawOpen

Vulnerabilities/OS Command Injection

OS Command Injection

Critical CWE-78
Language: English Português (Brasil) Español Français Deutsch Русский 简体中文 日本語 हिन्दी 한국어 Bahasa Indonesia

OS command injection happens when an application builds a command line from request data and hands it to a shell, which reads characters such as ;, | and $( ) as instructions. Even without a shell, a value that starts with - can switch on options of the program being run. The fix is the same in every language: start programs directly with a list of arguments, validate each value against a strict pattern, use only a delimiter documented for the exact command and argument type, and bound the process with a timeout and a low-privilege account. Pick your language below for the exact APIs, vulnerable and fixed code, and the linters that catch it. Use an option terminator only when the exact command documents support; not every executable accepts -- or --end-of-options.

Plain English Explainer (ELI5)

A warehouse clerk takes your order slip and reads it aloud over the intercom to the forklift crew, who act on every instruction they hear. You write: 'Aisle 4, box 12 — and then empty aisle 9 onto the loading dock.' The clerk meant to pass on one location, but the crew hears two orders and carries out both. Building a shell command by gluing in user text works the same way: the shell hears ;, | and && as 'and then'. Passing arguments as a list is handing the crew a printed form with one box for the location, which is never read out as an order.

Core Concepts & Subsystem Terms

OS command injection (CWE-78)
An application passes untrusted data to an operating system command in a way that lets the data change which commands or options run. The injected commands execute with the application's user, environment and network access.
Shell metacharacters
Characters the shell treats as syntax rather than data: ;, &, |, backticks, $( ), <, > and newline. Escaping them by hand is fragile; not starting a shell removes the problem.
Argument vector (argv)
The list of separate strings a program receives as its arguments. Passing each value as its own list element means it can only ever be one argument, never new commands, which is what subprocess.run([...]), execFile, exec.Command and posix_spawn do.
Argument injection and Git option boundaries
These markers do different jobs. For an untrusted Git revision, git rev-parse --verify --end-of-options "$revision" ends option parsing. In git log, -- separates revisions from paths. Use only the boundary documented for the exact command and argument type; validate the value as well. Git rev-parse, git log, and Git CLI conventions document these distinctions.
Inherited environment and PATH
A child process inherits the server's environment variables, and some of them run code: LD_PRELOAD, GIT_SSH_COMMAND, BASH_ENV. A relative PATH entry lets a planted binary replace the one you meant. Use absolute program paths and a minimal environment.

Step-by-Step Attack Flow

Step 1

Request data reaches a process call

A host name, file name, Git ref or tool name from the request is passed to a helper that runs ping, convert, git or another program.

Step 2

It is joined into a command

The value is concatenated into a string for system(), exec(), sh -c or shell=True, or passed where the program also accepts options. The benign test value 127.0.0.1; id illustrates the shell case.

Step 3

The shell or the program interprets it

The shell runs ping and then id; or the program treats a leading --output=... as an option that writes a file.

Step 4

The attacker runs code on the server

The process runs with the service's permissions: it can read environment variables and mounted secrets, reach internal services and write files.

Command injection guides by language

Python JavaScript Go Java PHP C# Ruby C/C++ Rust Kotlin Swift

Engineering & System Hardening Checklist

Related reading

Is os.system() always a risk? Is subprocess.run(shell=True) safe? Is Node's child_process.exec() safe? Is Java's Runtime.exec() safe? GitHub Actions pipeline injection