I'm writing a shell script that changes its behavior based on the number of positional parameters passed
# script.sh
if [ $# -eq 1 ]; then
if [ -f "$1" ]; then
validate='validate <"$1"'
else
validate='validate <<<"$1"'
fi
else
IFS=$'\n'
validate="validate <<<'${*}'"
fi
eval "$validate" | pull_data
Both validate
and pull_data
are Bash functions that read from stdin and write to stdout
If the first case [ $# -eq 1 ]
, I believe the code is safe from injection. Since the string is single-quoted, parameter expansion only happens after eval is called. I can't think of a string that could result in code injection here.
## Issue
The problem arise with the else
condition. Here, each positional parameters is expanded into a new line. For example
./script.sh "string_with_'_in_its_name" "code injected'"
The quote inside one of the first parameter causes subsequent new parameters to be interpreted as commands. Similarly, this also results in an injection vulnerability:
./script.sh valid_input \''$(code injected)'\'
## Context
I'm using eval to avoid repeating the validate ... | pull_data
construct in every if condition. The real script has many more conditions, and using eval makes it more readable.
Any advice on how to refactor this script to avoid the injection issue while maintaining readability would be greatly appreciated!
Asked by killua148
(3 rep)
Jan 5, 2025, 06:46 PM
Last activity: Jan 7, 2025, 09:18 AM
Last activity: Jan 7, 2025, 09:18 AM