Valószínűleg már mindenki olvasott a shellshock bugról amit bash-ban találtak. A bug kb. 20-25 éve van egyébként a bash-ban. Szinte mindenhol ugyanazt az egysoros példát említik amivel ellenőrízhetjük, hogy bugos-e a bash-unk (persze hogy az), de nem igazán magyarázzák el részletesen, hogy mi is a baj.
Környezeti változót valószínűleg már mindenki használt bash-ban:
$ echo $A
$ A=a
$ echo $A
a
Ha azt szeretnénk, hogy a környezeti változó értéke csak egyetlen parancs végrehajtásának idejére változzon meg, akkor egy sorban a következőt kell használnunk:
$ B=bb bash -c 'echo $B'
bb
$ echo $b
A környezeti változónak nemcsak konstans értéket adhatunk át, hanem egy függvény is akár:
$ C='() { echo $(($1+1)); }' bash -c 'C 2'
3
A gond ott van, hogy bár a függvény kódja véget ér a csukó kapcsos zárójelnél, a bash megengedi, hogy további kódrészletet írjunk oda, amit végrehajt:
$ C='() { echo $(($1+1)); }; echo vulnerable' bash -c 'C 2'
vulnerable
3
Ráadásul nemcsak akkor hajtja végre, ha meghívjuk a függvényt, hanem akkor is, ha nem:
$ C='() { echo $(($1+1)); }; echo vulnerable' bash -c 'echo x'
vulnerable
x
Ezután már elég jól érthető az az ellenőrző kód amit minden blog javasol:
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test
A :; igazából nem csinál semmit, de rövid és szintaktikailag helyes kódrészlet. Az env nem teljesen világos hogy miért kell, nekem működik anélkül is.