Web Application Security · intermediate · ~12 min

Command injection and path traversal

Explain OS command injection and path traversal and their correct fixes.

Overview

Command injection runs attacker shell commands when input is concatenated into a shell call (→ RCE); path traversal reads/writes arbitrary files via ../ sequences. Both share the injection root cause; fixes are argument-array APIs / no-shell, and canonicalized, base-directory-bounded paths.

Why it matters

Command injection is direct server RCE — among the most severe web findings — and path traversal exposes credentials, source, and config. Both recur constantly, and the correct fixes (no-shell argument arrays, canonical bounded paths) matter for accurate reporting.

Core concepts

Command injection. Shell metachars (;, |, `) in input → RCE; fix with argv APIs, not escaping. Path traversal. ../ and encodings escape the base dir; fix by canonicalize + containment check or filename allowlist. Shared root. Input becoming interpreter structure.

Lesson

Two file/OS-level injection classes that hand attackers the server.

OS command injection

When an app builds a shell command from user input:

ping -c1 <user_host>     →  user_host = "8.8.8.8; cat /etc/passwd"

the shell runs the appended command. Impact is immediate remote code execution as the web user. Fix: don't call the shell with user data. Use APIs that take an argument array (no shell), or strictly allowlist/validate input. Escaping shell metacharacters by hand is fragile.

Path traversal

When a filename comes from user input and isn't constrained:

GET /download?file=report.pdf      → intended
GET /download?file=../../etc/passwd → reads arbitrary files

../ sequences climb out of the intended directory. Encodings (%2e%2e%2f, double-encoding) bypass naive filters. Fix: resolve the canonical path and verify it stays within an allowed base directory; prefer an allowlist of filenames or an opaque ID → path mapping. Don't just strip ../ (bypassable).

Common thread

Both are the same root cause as SQL/NoSQL injection: untrusted input crossing into an interpreter (shell, filesystem) as structure. The cure is always to keep input as data — argument arrays, canonicalized+bounded paths, allowlists.

Summary

Command injection and path traversal are the OS/filesystem members of the injection family — input becoming shell or path structure. Keep input as data: argument arrays for commands, canonicalized base-bounded paths or allowlists for files.