Is the behavior behind the Shellshock vulnerability in Bash documented or at all intentional?

Solution 1:

This seems like an implementation bug.

Apparently, the way exported functions work in bash is that they use specially-formatted environment variables. If you export a function:

f() { ... }

it defines an environment variable like:

f='() { ... }'

What's probably happening is that when the new shell sees an environment variable whose value begins with (), it prepends the variable name and executes the resulting string. The bug is that this includes executing anything after the function definition as well.

The fix described is apparently to parse the result to see if it's a valid function definition. If not, it prints the warning about the invalid function definition attempt.

This article confirms my explanation of the cause of the bug. It also goes into a little more detail about how the fix resolves it: not only do they parse the values more carefully, but variables that are used to pass exported functions follow a special naming convention. This naming convention is different from that used for the environment variables created for CGI scripts, so an HTTP client should never be able to get its foot into this door.

Solution 2:

The following:

x='() { echo I do nothing; }; echo vulnerable' bash -c 'typeset -f'

prints

vulnerable
x () 
{ 
    echo I do nothing
}
declare -fx x

seems, than Bash, after having parsed the x=..., discovered it as a function, exported it, saw the declare -fx x and allowed the execution of the command after the declaration.

echo vulnerable

x='() { x; }; echo vulnerable' bash -c 'typeset -f'

prints:

vulnerable
x () 
{ 
    echo I do nothing
}

and running the x

x='() { x; }; echo Vulnerable' bash -c 'x'

prints

Vulnerable
Segmentation fault: 11

segfaults - infinite recursive calls

It doesn't overrides already defined function

$ x() { echo Something; }
$ declare -fx x
$ x='() { x; }; echo Vulnerable' bash -c 'typeset -f'

prints:

x () 
{ 
    echo Something
}
declare -fx x

e.g. the x remains the previously (correctly) defined function.

For the Bash 4.3.25(1)-release the vulnerability is closed, so

x='() { echo I do nothing; }; echo Vulnerable' bash -c ':'

prints

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'

but - what is strange (at least for me)

x='() { x; };' bash -c 'typeset -f'

STILL PRINTS

x () 
{ 
    x
}
declare -fx x

and the

x='() { x; };' bash -c 'x'

segmentation faults too, so it STILL accept the strange function definition...