Stavek goto povzročil ranljivost v SSL/TLS
V zadnjih tednih so odkrili dve ranljivosti pri implementaciji protokolov SSL/TLS, ki sta si presenetljivo podobni. Apple je svoja operacijska sistema iOS in Mac OS X zakrpal kmalu po odkritju, potem pa so dobra dve tedna pozneje sorodno ranljivost našli še v odprtokodni knjižnici GnuTLS, ki je tudi že zakrpana v verziji 3.2.12.
Obema je skupno tudi to, da je koda v prizadetem delu odprta in javnosti dostopna, pa to ni dolgo časa ni odkrilo napake. Napaka v Applovi kodi, o kateri smo že pisali, je posledica ponovljenega stavka goto v kodi. Ta se za pogojnim stavkom if ponovi dvakrat, kar je ena izmed bolj zahrbtnih napak. Ker zanki ne sledijo zaviti oklepaji, je prevajalnik v skladu s sintakso jezika C++ ne razume kot blok, ampak je vsebina zanke if le prvi stavek goto. Drugi je samostojen in se izvede vsakokrat. Zaradi tega rutina preskoči pomemben del preverjanja veljavnosti certifikata, kar v praksi pomeni, da mu lahko podtaknemo kakšnega, ki je podpisan s katerimkoli drugim veljavnim ključem, pa bo preverjanje pristnosti vseeno uspešno.
Zelo podobna napaka pri uporabi stavkov goto se je primerila tudi v knjižnici GnuTLS, ki jo uporablja cela vrsta odprtokodne programske opreme. Tu več pogojnih stavkov if kliče napačno interno funkcijo (cleanup namesto fail), kar ima sorodne posledice. Tudi GnuTLS je mogoče pretentati in mu podtakniti certifikat X.509, ki ga ni podpisala obiskana stran. Omenjena ranljivost je po nekaterih podatkih v GnuTLS obstajala vse od leta 2005 (!), pa je ni odkril nihče.
Eden izmed argumentov za uporabo odprtokodne programske opreme je prav možnost pregleda kode, ki bi v teoriji morala preprečiti tovrstne spodrsljaje. Toda to deluje le, če ljudje kodo dejansko ponovno preberejo, preverijo in prevedejo. Samo odprtje kode, ki leži v repozitorijih in je nihče ne kontrolira, seveda ne koristi nikomur. Prav GnuTLS je problematičen, saj so že v preteklih letih na internetu redno pojavljale kritike, da je napisan zelo pomanjkljivo in površno, kot da avtorji ne bi bili kos nalogi. Prav mogoče je, da je odkritje ranljivosti v Applovi opremi vzpodbudilo natančnejši pregled GnuTLS, ki je potem pokazal sorodno napako. Ni torej res, da odprtje kode avtomatično prepreči tovrstne napake.
Pedantni programerji so bržkone že zastrigli z ušesi ob omembi stavkov goto. Po Böhm-Jacopinijevem izreku je mogoče vsak program napisati brez uporabe stavka goto. Šola lepega programiranja uči, da je uporaba teh stavkov nezaželena, ker zmanjšuje preglednost kode in v primeru neprevidne rabe daje kodo (»špagetasta koda«), ki jo je težko popravljati in razhroščevati. Vseeno številni programski jeziki ukaz goto še podpirajo in v nekaterih primerih lahko z njegovo pametno uporabo dejansko poenostavimo in skrajšamo program.
Zato bi bilo krivično odkriti napaki pripisati stavku goto. Razlog sta nepazljivost in malomaren (ali neobstoječ) pregled kode.