https://gist.github.com/alganet/a4198158651f3b2dc43ce658052e...
Then, if we run it:
"line 3: test: a[$(cat /etc/passwd > /tmp/pwned)] + 42: integer expression expected"
Yep, this is specifically a bashism (by way of being a kshism). However, it's worth noting that the second variant (`type -v`) will work in `[` and `test`.
(It's also a still a bashism, but IME people don't realize how little of `type` is actually POSIX.)
For reference, this works for me in Bash 5.2:
test -v 'x[$(cat /etc/passwd)]'
I just declare all of my shell scripts to use bash, since I've got no idea how much of anything is a bashism versus POSIX, and I hate shell scripts enough that I don't care to learn.
Yes, you can do dangerous things in bash scripts. This might be one of them. Not at my computer now and no time to experiment.
IMO safe shell scripting is kind of dead. I can do it if I really have to, but too many external programs have tricky "convenience" features like interpreting flags after positional parameters, etc.
(and where '[' is simply an alias to 'test')
As a less joke but also more joke: https://www.gnu.org/software/emacs/manual/html_mono/eshell.h...
1: it was going to be much funnier if I could have found the link where someone used emacs as Xsession or similar but this one will do
Shellcheck currently gives Sample 1 a pass. I hope this is something it can be modified to catch.
${num}
is completely useless. Inside [[ bash does not do any word splitting after variable expansion. Double quotes never prevent variable expansion. I am not sure what the author is talking about. Shellcheck is correct to not complain. I stopped reading there.I think it would behoove you to read the rest of the post. The double quotes are not the operative part of example there; they're only there to demonstrate that the code execution doesn't come from splatting or word splitting.
The actual code execution in Case #1 comes from the fact that bash (and other ksh descendants) run arithmetic evaluation on some strings in arithmetic contexts, regardless of their double or single quoting. That evaluation, in turn, can run arbitrary shell commands.
Myself I typically don't script in bash. Most of the extras like [[ are not needed, you can do everything in dash. Arrays are the only feature that comes to my mind where bash would be handy.
Showing -eq is not the best example, it can just be replaced by = and the problem goes away.
But if you need -gt or similar there is no replacement. So one should stick to [.
If I follow correctly the dangerous combination is [[ and arithmetic comparisons?
The dangerous thing here is that an undefined number of contexts exist where Bash treats strings as arithmetic expressions, which can contain arbitrary code despite not being quoted for expansion. `-eq` is just one example of that; others have linked other examples.
(This is all for case #1. With case #2, `[` and `test` are also susceptible so long as their builtin variants are used.)
$ [[ 0xFF -eq 255 ]] ; echo $?
0
$ [[ 0xFF = 255 ]] ; echo $?
1
The "good news" is that bash is so full of ways to get command execution that people blow their foot off and get compromised long before these little details are what are compromising their system. People get popped putting in user input at the base string layer where all you have to do is slap down a semi-colon to get arbitrary command execution long before they're getting popped by obscure "test" behaviors.
Serious, please view the curled file from a link before piping it to bash/sh.
We all want bash gone, but it is an essential piece of infrastructure. The introduction of dash was a huge step in this direction (of ditching bash).
Do you want to help? Try to remove bash from the toolchain bootstrap. It is one of the lowest hanging fruits right now.
xonsh is neat in principle, but painful in actual usage ime. And I suspect vulnerable to similar issues around the Python-bash interop.
Let's say you need to install some third party software that is pretty standard `./configure && make && make install`, what would you do? Port `configure` to python?
Basically, the -v case was by design, so for `-v 'hash[$key]'`, "$key is expanded before the array subscript evaluation, and then the whole array plus expanded index is evaluated in a second pass". "Newer versions of bash (5.0 and higher) have a assoc_expand_once option which will suppress the multiple evaluations"
Note that the `-v` case doesn't really work the way one may infer from reading the OP:
> $ key='$(cat /etc/passwd > /tmp/pwned)'
> $ [[ -v 'x[$key]' ]]
> bash: $(cat /etc/passwd > /tmp/pwned): syntax error: operand expected (error token is "$(cat /etc/passwd > /tmp/pwned)") *
> [[ -v "${x[$key]}" ]]
> bash: $(cat /etc/passwd > /tmp/pwned): syntax error: operand expected (error token is "$(cat /etc/passwd > /tmp/pwned)")
function guess () { declare -i num="${1}" ; }
(unless I'm missing something?)if you try to evaluate this kind of things as an arithmetic expression directly, it will fail with an error of a bad subscript (mind you, the attack will still work though).