0

$somevariable may contain whitespaces and other special characters to bash, and introduce security risk. Are the following commands equivalent? If not, can you rank them?

bash -c 'somecommand "$1"' bash "$somevariable"
bash -c "somecommand '$somevariable'"
bash -c "somecommand \"$somevariable\""

Are the following commands equivalent? If not, can you rank them?

find -exec sh -c 'something "$@"' sh {} \;
find -exec sh -c "something '{}'" \;
find -exec sh -c "something \"{}\"" \;
find -exec sh -c 'something "{}"' \;

I can't find nonequivalence between the commands in each group.

Originated from Ways to provide arguments to a command executed by `bash -c`. Here I would like to figure out whether the reason why findutils manual suggests

find -exec sh -c 'something "$@"' sh {} \;

instead of

find -exec sh -c "something {}" \;

is because of

  • quoting or

  • moving {} outside of the command to be executed by sh -c

Will the other commands I wrote in the second group above also work equivalently well?

Thanks.


To attack find -exec sh -c "something '{}'" \; the second command in the find group:

$ touch "'; echo world '"
$ find . -exec sh -c "ls '{}'" \;
''\''; echo world '\'''
''\''; echo world '\'''
world 
Tim
  • 101,790
  • 1
    Didn't Stephen already answer essentially this question in https://unix.stackexchange.com/a/448449/170373 ? – ilkkachu Jun 10 '18 at 08:22

1 Answers1

6

The bash -c commands are not the same in at least the following examples:

$ var='a
$(uname)'

$ bash -c 'echo "$1"' bash "$var"
a
$(uname)

$ bash -c "echo '$var'"
a
$(uname)

$ bash -c "echo \"$var\""
a
Darwin

The find commands also differ:

$ touch 'a
> $(uname)'

$ find . -exec sh -c 'echo "$@"' sh {} \;
.
./a
$(uname)

$ find . -exec sh -c "echo '{}'" \;
.
./a
$(uname)

$ find . -exec sh -c "echo \"{}\"" \;
.
./a
Darwin

$ find . -exec sh -c 'echo "{}"' \;
.
./a
Darwin

So it seems that the following allow arbitrary code execution:

  • bash -c "echo \"$var\""
  • find . -exec sh -c "echo \"{}\"" \;
  • find . -exec sh -c 'echo "{}"' \;
jesse_b
  • 37,005