# Command, Template and Other Injection — OWASP Top 10

Source: https://www.skillbyai.com/en/owasp-top-10/n-command

> The same pattern in other interpreters.

## Avoid interpreters for untrusted input

Injection applies to any interpreter: **OS commands** (input passed to a shell), **server-side templates** (user input compiled as a template), LDAP, XPath, NoSQL query operators and even LLM prompts. Prefer library APIs over shelling out; when you must run a program, pass arguments as a **list without a shell** and validate them against an allow-list. Never render user input as a template, and validate input types strictly (for example reject objects where strings are expected in NoSQL queries).

## Shell injection and the safe alternative

Python subprocess.

```python
import subprocess

# VULNERABLE: "file.png; rm -rf /" runs a second command
subprocess.run(f"convert {filename} out.jpg", shell=True)

# SAFER: no shell, arguments as a list, input validated
import re
if not re.fullmatch(r"[A-Za-z0-9_-]{1,64}\.png", filename):
    raise ValueError("invalid file name")
subprocess.run(["convert", filename, "out.jpg"], check=True, timeout=30)
```

## Validate types, not just strings

A JSON body like {"password": {"$ne": null}} can bypass naive NoSQL login checks; require a string.

**Quiz:** What is the safest way to run an external program with user-supplied input?

- [ ] Concatenate strings carefully
- [ ] Use shell=True with quotes
- [x] Pass arguments as a list without a shell, after allow-list validation
- [ ] Run it as root

*Answer:* Pass arguments as a list without a shell, after allow-list validation. Avoid the shell interpreter.
