RedTeam Nexus Labs
Module 12 · Lesson 01 // Command Injection

OS command boundaries

Command Injection · Web Security

Freereading · 10 min
On this page
LESSON

Overview

Command injection occurs when an application passes untrusted input to the operating system as part of a command. To understand it, you first need to understand how programs invoke OS commands and where the dangerous boundary lies. This lesson covers OS command boundaries.

Learning objectives

  • Explain how applications invoke OS commands.
  • Identify the boundary between a program and a shell.
  • Recognize where untrusted input becomes dangerous.

Core concept

Applications sometimes need to run operating-system commands (e.g. to process a file, call a system tool). There are two broad ways to do this:

  • Via a shell — the command is passed as a string to a shell interpreter, which parses it (interpreting spaces, quotes, and metacharacters like ;, |, &). This is where injection risk is highest.
  • Directly (no shell) — the program executes a specific binary with an explicit array of arguments, bypassing shell parsing.

The crucial boundary is between command structure (the program and its intended arguments) and data (values passed to it). Command injection arises when untrusted input crosses into the structure.

How it works

When a command is run through a shell, the shell interprets metacharacters, so any untrusted input placed in the command string can potentially introduce additional commands or operators — the essence of command injection. When a command is run directly with an argument array, the OS treats each array element as a literal argument to the named program, with no shell parsing, so untrusted values cannot introduce new commands. Understanding this boundary explains both why injection happens (shell string construction) and how the primary defense works (avoid the shell / separate arguments).

Practical example

Suppose an app runs a system utility on a user-supplied filename. If it builds a single command string and hands it to a shell, the shell will interpret metacharacters in that string — so input containing shell operators could be parsed as extra commands. If instead the app invokes the utility directly with the filename as a separate argument (no shell), the filename is treated purely as data — a literal argument — and cannot spawn new commands. The difference lies entirely at the shell boundary. (Concrete prevention is developed in later lessons.)

Cybersecurity relevance

Command injection is among the most severe web vulnerabilities because it can lead to arbitrary command execution on the server — often full system compromise. It hinges on the OS-command boundary: passing untrusted input through a shell as part of a command string is the dangerous pattern. Recognizing when an application shells out, and where user input enters that command, is the first step to both finding and preventing command injection — the focus of the rest of the module.

Common mistakes

  • Passing user input through a shell as part of a command string.
  • Not distinguishing shell invocation from direct execution with an argument array.
  • Assuming "it's just a filename" is safe when it flows into a shell command.

Key takeaways

  • Applications run OS commands either via a shell (which interprets metacharacters — high risk) or directly with an explicit argument array (no shell parsing — safer).
  • Command injection arises when untrusted input crosses from data into command structure, primarily through shell string construction.
  • Command injection can yield arbitrary command execution and full server compromise; recognizing the OS-command boundary is the basis for prevention.

Check your understanding

  • What is the key difference between running an OS command via a shell versus executing a binary directly with an argument array?
  • Why does passing untrusted input through a shell create command-injection risk?
FINISH THIS LESSON

Sign in to save your progress.