Is it possible to pass some executable shell code by setting env USER=..some code... ./script.sh, given that the script itself either uses echo $USER or tmpdir=/var/tmp/log-$USER


You can pass shell code in an environment variable to a script, no problems, but the script would need to expect shell code in the variable and evaluate it as such:

See e.g. the difference between

$ env USER='$(echo hello)' bash -c 'echo "$USER"'
$(echo hello)


$ env USER='$(echo hello)' bash -c 'eval "echo \"$USER\""'

In both of the above commands, a piece of code is passed in $USER to the bash -c script. The code is a simple command substitution that would output the string hello if evaluated, and the calling shell would not evaluate the command substitution since it is a string within single quotes. The first bash -c script does not evaluate the string, so it prints the shell code. The second bash -c script evaluates the passed string as part of a call to echo, and therefore prints echo (it basically runs echo "$(echo hello)".

This way of solving your issue is brittle and dangerous, as it allows a user to pass arbitrary shell code into your script (in fact, it relies on being passed code and you execute it unconditionally). It's a typical code injection vulnerability.

What I think that you want to do is to pass a string, not shell code:

$ env USER="$(echo hello)" bash -c 'echo "$USER"'

Here, the variable USER is set to the string hello before calling the bash -c script (since the shell would expand the command substitution within the double quotes). The script then takes the string and echoes it. In your case, the script would take the string and use it as part of a pathname.

The point is that the string is computed by the user before the script gets it.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.