Bash Injection Safe Input
Bash injection-safe input is input handled so it can never become code. Data stays data when the shell never parses it a second time.
Eval turns crafted input into a running command
The input looks like plain text, but eval parses it again. The hidden command runs and prints its marker.
input='$(echo INJECTED)'
eval "echo $input"Quoting the same input prints it harmlessly
With quotes and no eval, the shell prints the value as text. Nothing inside it runs.
input='$(echo INJECTED)'
echo "$input"A whitelist refuses unknown actions
The known word runs its fixed action. The crafted word matches no case, so it is refused.
run() {
case "$1" in
list) echo "listing files" ;;
*) echo "refused" ;;
esac
}
run list
run '$(echo INJECTED)'Example
input='$(echo INJECTED)'
eval "echo $input"
case "$input" in
greet) echo "hello" ;;
*) echo "refused" ;;
esacKey points
- Eval re-parses: eval runs its argument as code, so crafted input inside it executes.
- Quoting neutralises: "$input" prints the value as plain text, never as code.
- Command substitution hides in data: $(...) inside evaled input runs.
- Whitelist dispatch: a case statement that only accepts known words refuses everything else.
- Arrays hold data safely: storing words in an array keeps them as separate arguments, not code.
- Never build commands from input: joining user words into a command string invites injection.
In this example, the same crafted input is handled two ways. First, eval re-parses it, so the hidden command runs and prints INJECTED. Then a case whitelist checks the input against known words only, finds no match, and refuses it.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
An input of $(echo INJECTED) is passed to eval. What happens?