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 ]
