One of my bash scripts contains this test:
if [ ! -v "$3" ]; then
exit
else
...
fi
Is there a way to inject data in $3 argument that will execute something nasty ? (my script is run with suid privilege and contains sensitive variables...)
Thanks
CodePudding user response:
Yes, there is an injection vulnerability here. The problem is that -v
test evaluates its argument as a variable, and in bash that can include an array element (e.g. arrayVar[5]
), and since array indexes (for non-associative arrays) are numbers, the index part gets evaluated as an arithmetic context, which can include command substitutions.
So if $3
is something like this:
x[$(touch /tmp/pwned)]
...or, if you're worried about sensitive variables:
x[$(echo "$SensitiveVar" >/tmp/pwned)]
...it'll wind up executing the part inside $( )
, with privilege and access to internal shell variables.
Note that since this occurs because of how the -v
test is evaluated, quoting $3
doesn't help, and neither does using [[ ]]
instead of [ ]
.
CodePudding user response:
No. Since the variable is quoted, it's simply expanded and the result is treated as a single word in the expansion. No further processing is done with the result. Quoting a variable is the sure way to prevent code injection in shell scripts, unless you pass the expansion to something else that executes it. E.g.
ssh hostname "$3"
doesn't execute $3
locally, but the remote server will execute it.
Note that [ -v "$3" ]
doesn't test whether $3
is set, it expands $3
, which should contain the putative variable name, and tests whether that variable exists. If you want to know whether $3
exists, you would have to use [ -v 3 ]
or [ $# -ge 3 ]