Heartbleed, Shellshock i krhki temelji

Pola interneta je vjerovalo zelenom lokotu, a lokot je čuvao jedan umoran doktorand i par volontera bez plaće — dobrodošli na obdukciju Heartbleeda.

poglavlje 22/2619 min čitanja2011 – 2019

Travanj 2014. U prethodnom poglavlju smo zeleni lokot pretvorili u religiju. Snowden je progovorio, svijet je pojurio u HTTPS kao u bunker, i na tren se učinilo da smo shvatili lekciju: šifriraj sve, vjeruj matematici, spasi se od velikog brata. Lokot je svijetlio zeleno u adresnoj traci, malen, umirujuć, gotovo domaći — kao lampica na aparatu za dijalizu koja kaže da je sve u redu. Nitko nije pitao tko servisira taj aparat.

Ime pacijenta glasi OpenSSL. Ako niste čuli za njega, nije čudno — nije trebao biti poznat, trebao je biti nevidljiv, kao vodovod ili kanalizacija u zidu. Radio je posao koji nitko ne slavi: kriptirao je bankovne transakcije, mailove, VPN veze, prijave na Facebook — otprilike pola interneta koji si taj dan otvorio dok si čekao kavu. Radio je taj posao dobro, koliko je znao. A znao je manje nego što je svijet mislio.

Ovo poglavlje je obdukcija — ali ne obdukcija OpenSSL-a, koji je, tehnički, još živ i disao je i nakon svega o čemu ćemo pisati. Obducirat ćemo iluziju koja je umrla 7. travnja 2014., u trenutku kad je objavljena ranjivost s imenom dovoljno dramatičnim da dobije logo prije nego što je dobila zakrpu: Heartbleed, „krvarenje srca”. Poetično, za promjenu — obično se sigurnosne rupe zovu poput kataloških brojeva, ova je zaslužila naslov.

Na stolu obdukcijske sale, dakle, ne leži čovjek nego uvjerenje. Uvjerenje da infrastruktura na kojoj stoji internet ima nekakvu težinu, nekakvu institucionalnu masu — vojsku inženjera u sivim uredima koja bdije nad ključnim bibliotekama kao nad nuklearnim reaktorom. Skalpel će pokazati suprotno: temelj je bio jedan umoran čovjek, jedna sitna promjena koda ubačena kasno navečer (u žargonu programera to se zove „commit” — zamisli ga kao potez u šahu koji upišeš u bilježnicu i nikad više ne provjeriš je li bio dobar), i šačica volontera koja održava kod od kojeg zavisi planet — bez plaće, bez pritiska, s onoliko pažnje koliko ostane nakon pravog posla i obiteljske večere.

Dvije godine je ta rupa curila neopaženo. Dvije godine je svatko sa strpljenjem i internetskom vezom mogao poslati serveru sitan, naizgled bezazlen upit — samo šapat od nekoliko bajtova, kao lozinku za tajna vrata — i dobiti u zamjenu šezdesetičetiri kilobajta njegove memorije: lozinke, privatne ključeve, komadiće tuđih tajni, nasumično, kao da vadiš papire iz razderane vreće za smeće. A lokot je, cijelo to vrijeme, svijetlio zeleno.

Dobro, otvorimo pacijenta. Prije nego zarežemo, pogledajmo dokumentaciju — jer svaka dobra obdukcija počinje s pitanjem što je uopće trebalo biti zdravo. Zeleni lokot u adresnoj traci. Znaš ga. Klikneš na njega, ponekad, kao da ćeš dobiti neku tajnu poruku, a dobiješ rečenicu o certifikatu koju ne razumiješ — ali lokot je zelen, i to je dovoljno. Lokot znači: netko je ovo zaključao. Netko pazi. Ta poruka putuje kroz otprilike dvije trećine cijelog interneta zahvaljujući jednoj biblioteci koja se zove OpenSSL.

Zamisli OpenSSL kao vodovod zgrade: nitko ne razmišlja o cijevima dok voda curi na pravo mjesto. Kad kažeš da je stranica „sigurna”, u velikoj većini slučajeva to zapravo znači da je negdje duboko OpenSSL, ili nešto od njega izvedeno, odradilo posao i zaključalo vrata. Ti vidiš lokot. On je cijeli sustav brava.

Travanj 2014. Dišemo teško. Otkriva se rupa u OpenSSL-u koja dobiva ime — Heartbleed — i logo, jer 2014. je već ta godina kad su sigurnosne rupe postale brendovi. Ime nije slučajno slikovito: rupa je bila u dijelu koda koji se zove heartbeat, otkucaj srca. Ideja otkucaja je bezazlena — kad se dvije strane spoje preko sigurne veze, s vremena na vrijeme jedna pošalje drugoj malu poruku tipa »jesi još tu?«, zajedno s podatkom koliko je duga ta poruka, da bi druga strana znala točno koliko slova da vrati. Kažeš: »pošalji mi natrag 4 slova«, i priložiš te četiri slova. Server ih vrati. Otkucaj. Sve u redu.

Bug je bio u tome što nitko nije provjeravao poklapa li se ta izjava — »šaljem ti 4 slova« — sa stvarnom duljinom poruke koju si zapravo poslao. Ti kažeš da šalješ 4 slova, ali fizički priložiš samo jedno slovo, i onda dodaš: a vrati mi, molim te, 64 kilobajta. Server, poslušan i lud kao kavalir koji ne postavlja pitanja, kopira 64 kilobajta iz svoje radne memorije — bilo što se tamo trenutno zateklo — i pošalje ti to natrag. A u toj memoriji, u tom trenutku, mogu biti lozinke koje je netko upravo upisao, privatni ključevi kojima server dokazuje svoj identitet, kolačići prijava, komadi tuđih razgovora. Ne moraš probiti nikakvu bravu. Samo pitaš servera da ti očita svoju vlastitu glavu, naglas, i on to poslušno radi.

To je cijela rupa. Nema genijalnog napada, nema egzotičnog alata, nema filmske scene s brzim tipkanjem u zelenom fontu. Jedna provjera koja nedostaje, jedna if-linija koja se nije pitala poklapaju li se brojevi, i cijela zgrada povjerenja — banke, vlade, tvoj mail — otvorena za bilo koga tko je znao postaviti pitanje na pravi način. Lokot je bio zelen sve to vrijeme. Vrata su, unatoč tome, bila širom otvorena. I sad, prije nego pitamo tko je to napisao i zašto ga nitko nije uhvatio, moramo priznati dijagnozu koju smo upravo postavili pacijentu: nije bio bolestan od nedavno. Bio je bolestan otkad ga je ikad tko dotaknuo, a mi smo samo pretpostavili da je zdrav, jer je izgledao ozbiljno.

Uzrok smrti #1: jedan umoran čovjek
§ 02

Uzrok smrti #1: jedan umoran čovjek

Vrijeme je za patologiju. Kad forenzičar otvori pacijenta i traži uzrok smrti, ne traži zlog čovjeka s nožem. Traži trenutak — onaj jedan, banalan, u pravilu prazničan trenutak — kad je nešto krenulo krivo i nitko to nije primijetio. U slučaju Heartbleeda taj trenutak ima datum, ime i, koliko je poznato, dobre namjere. Prosinac 2011., njemački doktorand po imenu Robin Seggelmann šalje commit u kod OpenSSL-a. Radi na proširenju heartbeat funkcije — onoj koja, sjećaš se, služi da dva računala povremeno kažu jedno drugom »još sam živ, javi mi koliko primiš«. Dodaje kod. Negdje u tom kodu ne provjerava je li duljina koju klijent tvrdi da šalje ista kao duljina podataka koje stvarno šalje. Sitnica. Jedna linija koja nedostaje. Piše to, kako sam kaže, na Staru godinu navečer, malo umoran, i pošalje. Nema u tome zlobe, nema urote, nema državnog aktera koji ubacuje stražnja vrata — ima samo čovjeka koji je vjerojatno htio otići na spavanje.

Ovo je važno zapamtiti dok tražimo krivca, jer mozak voli krivca s licem i planom. Ovdje ga nema. Ima programera koji je napravio grešku koju je napravio svaki programer koji je ikad pisao kod koji obrađuje podatke stigle od nepoznatog izvora — samo što je njegova greška sjedila u biblioteci koja štiti pola interneta, umjesto u nekom internom alatu koji vidi troje ljudi. Isti bug, u drugom kontekstu, ostaje anegdota na pregledu koda. Ovdje postaje CVE broj koji ćeš pamtiti — CVE je, pojednostavljeno, matični broj za greške: svaka otkrivena sigurnosna rupa dobiva svoju standardiziranu katalošku oznaku, baš da bi cijeli svijet, od sigurnosnih stručnjaka do novinara, znao da govori o točno istoj rupi, a ne o nekoj sličnoj.

I tako bug ostaje. Ne dan, ne tjedan. Dvije godine. Uveden krajem 2011., otkriven u travnju 2014. — u međuvremenu je ušao u sve verzije OpenSSL-a koje su stigle na tržište, u milijune servera, uređaja, rutera, u sve što je itko postavio u tom razdoblju vjerujući da postavlja nešto provjereno. Dvije godine u divljini znače dvije godine u kojima je — teoretski — svatko s dovoljno znanja i strpljenja mogao slati te namjerno iskrivljene heartbeat pakete i čitati po 64 kilobajta tuđe memorije, u tišini, bez traga u logovima, koliko god puta je htio.

A sad dolazimo do brojke koja je, u punom kliničkom smislu, šokantna. Biblioteka OpenSSL u tom trenutku štitila je procjenjivano dvije trećine svih HTTPS servera na svijetu — banke, vlade, bolnice, tvoj router kod kuće. Koliko je koštalo njezino održavanje? Zaklada koja stoji iza projekta, OpenSSL Software Foundation, u godinama prije Heartbleeda živjela je od donacija koje su se mjerile u — pazi sad — nekoliko tisuća dolara godišnje. Ne milijuna. Tisuća. Projekt je imao jednog čovjeka koji je radio punovremeno, na plaći koja bi u Silicijskoj dolini prošla kao pripravnička, plus šaku volontera koji su ovo radili uz redovan posao, uz obitelj, uz spavanje koje nisu spavali.

Dakle, nalaz broj jedan ove obdukcije glasi ovako: pacijent nije umro od jednog zlog uboda. Umro je od kronične pothranjenosti koju je svijet dijagnosticirao kao zdravlje, jednostavno zato što pacijent dotad nije pao. Jedan umoran čovjek napravio je grešku koju je mogao napraviti svatko. Ništa je nije uhvatilo, jer nitko nije bio plaćen da hvata. I dvije godine je ta greška samo čekala, u memoriji servera cijele planete, dok je svijet — uključujući mene i tebe — sretno klikao na zeleni lokot pored adrese preglednika, vjerujući da taj lokot znači nešto više od toga da je netko, negdje, jednom davno, uopće instalirao vrata.

Uzrok smrti #2: "many eyes" mit
§ 03

Uzrok smrti #2: "many eyes" mit

Sljedeći nalaz u ovoj obdukciji tiče se jedne teorije koja je do travnja 2014. imala status medicinske činjenice open-source svijeta — Linusova zakona, onog istog koji smo secirali u poglavlju o kernelu: dovoljno očiju i svaki bug postaje plitak. Dovoljno ljudi gleda kod, pa netko će prije ili kasnije primijetiti da nešto smrdi. Lijepa teorija. Zvuči kao demokracija koda — svi pazimo jedni na druge, kolektivni imunitet protiv gluposti. Patolog sad mora postaviti neugodno pitanje: je li teorija bila pogrešna, ili je pogrešna bila pretpostavka da su te oči uopće bile tamo?

Odgovor, kao i u svakoj dobroj obdukciji, glasi: i jedno i drugo, ali više drugo. Oči jesu gledale kod. Milijuni njih, svaki dan, godinama. Samo nisu gledale ovaj kod. Gledale su React komponente, gledale su novu async/await sintaksu, gledale su kako netko elegantno rješava routing u nekom frameworku koji će za dvije godine biti mrtav. Gledale su, drugim riječima, ono što je zanimljivo, novo, na CV-u lijepo za napisati. Nitko ne budi subotom ujutro s mislima: danas bih volio pročitati dvogodišnju implementaciju heartbeat proširenja u knjižnici koju svi koriste, a nitko ne spominje. Zvuči kao dobrovoljni rad u kanalizaciji — nužan, spašava grad, ali baš nitko se ne javlja.

Pa dobro, reći će netko, ali koliko je onda uopće ljudi stvarno gledalo taj konkretan komad koda prije travnja 2014.? Odgovor je otužno malen. OpenSSL je u trenutku kad je Heartbleed puknuo imao otprilike desetak ljudi koji su ga uopće mogli mijenjati, od kojih je punovremeno na projektu radila — pazi sad ovu brojku, vrijedna je ponavljanja — jedna osoba. Jedna. Na knjižnici koja je štitila banke, vlade, bolnice i pola weba koji je nosio onaj zeleni lokot iz prethodnog poglavlja. Ne deset tisuća očiju. Ne tisuću. Ne ni pedeset. Nekoliko pari, umornih, koji su uz to imali i redovan posao.

Sad, poštenja radi — a obdukcija bez poštenja je samo linč u laboratorijskom mantilu — treba reći i drugu stranu medalje. Kad je Heartbleed konačno otkriven, zakrpa nije čekala mjesecima kroz korporativne odbore i sastanke o sastancima. Izašla je isti dan. Kod je bio otvoren, svatko je mogao pogledati što se točno popravlja, svatko je mogao provjeriti je li server na koji se oslanja pogođen, jer nije trebao čekati da mu neka firma milostivo objavi patch notes s tri rečenice nejasnog teksta. To je bila prava snaga modela — transparentnost koja liječi brzo, čak i kad je ta ista transparentnost ono što je bolest pustilo da se vidi svima, uključujući one koji su možda htjeli iskoristiti prozor prije zakrpe.

I upravo je to najneugodniji nalaz ove sekcije obdukcije: otvorenost koda je dvosjekli skalpel. Ista činjenica koja omogućava da tisuće ljudi teoretski mogu pročitati svaki redak jest i razlog zašto se svi pouzdaju da će to netko drugi učiniti. Vidljivost nije isto što i pažnja. Kod je bio otvoren kao vrata na ulici — samo što je ulica bila prazna, a svi su pretpostavljali da netko drugi hoda tim kvartom i pazi na susjede.

Shellshock i lavina
§ 04

Shellshock i lavina

Patolog jedva stigne skinuti rukavice od Heartbleeda kad zvoni telefon iz mrtvačnice. Rujan 2014. Novi leš, ista policija, drugačiji uzrok — ili baš isti, samo u drugom kostimu. Ovog puta pacijent se zove Bash. Ako OpenSSL nije zvučao glamurozno, Bash je još manje glamurozan: to je shell, ono crno sučelje u koje kucaš komande, potomak Bourne shella iz sedamdesetih, alat toliko temeljan da ga koriste milijarde uređaja — Linux serveri, ruteri, kamere, industrijski kontroleri, uključujući onaj router kod kuće koji nisi restartao otkad ga si kupio. I u njemu je, otkriva se, rupa stara koliko i sam Bash. Konkretno: 1989. Bomba koja tiktaka duže od pada Berlinskog zida, duže nego što neki od ljudi koji su je te godine zakrpali imaju godina.

Sekcijski nalaz: uzrok smrti je isti kao u prošlom poglavlju, samo lokacija rane druga. Shellshock — ime koje mu je dala industrija, jer sirovi CVE broj ne prodaje naslovnice — funkcionira tako da Bash, kad učitava environment varijable (skup podataka i postavki koje operativni sustav ili shell drži pri ruci svakom programu dok radi — putanje do datoteka, korisničko ime, jezik sustava i slično), ne zna prepoznati gdje prestaje definicija funkcije i počinje izvršavanje koda. Reci mu varijablu koja izgleda kao funkcija, a onda joj na kraj zalijepi pravu naredbu, i Bash će je poslušno izvršiti. Nema lozinke, nema autentikacije, nema pitanja. Samo: evo ti shell na tuđem serveru, izvoli. Isti obrazac kao heartbeat prije pola godine — jedna funkcija, napisana da bude korisna, koja u praksi otvara vrata čitavoj kući.

Tu se, patološki gledano, potvrđuje uzorak koji smo upravo utvrdili kod OpenSSL-a, samo dublje urezan. Bash nema OpenSSL-ov barem-donekle-organizirani tim; Bash ima jednog glavnog održavatelja i povremene priloge zajednice, a kod Bourne shella ispod njega nitko živ ne dira, jer ga se, sasvim razumno, boji. Netko je davno nacrtao strip koji je to zgodno sažeo — kritična infrastruktura interneta koju održava jedan umoran, nepoznati tip, dok se cijela zgrada moderne civilizacije oslanja na taj toranj od kockica. Strip je izašao 2020., pametan i precizan. Shellshock se dogodio uživo, u prirodi, šest godina prije. Umjetnost ne prati stvarnost — stvarnost samo čeka da je netko konačno nacrta.

A onda dolazi ono što obdukcija najviše voli: recidiv, samo bučniji. Heartbleed i Shellshock nisu bili incidenti, bili su najava žanra. Odmah iza njih niže se procesija — POODLE, FREAK, DROWN, sve redom rupe u temeljnim protokolima i bibliotekama, i sve odjednom dobivaju vlastita imena, logotipe, čak i web stranice s brojačem dana od otkrića. Industrija je shvatila da je katastrofa u infrastrukturi dovoljno redovita pojava da joj treba branding. Nekad je bug bio samo broj u nekoj bazi podataka, jedan od tisuća CVE oznaka koje nitko osim struke ne pamti. Sad je proizvod s identitetom, gotovo pa maskota.

Ono što se, međutim, ne mijenja iz slučaja u slučaj jest lokacija rane. Nikad se ne otkrije rupa u nekom sjajnom, novom, dobro plaćenom dijelu sustava. Uvijek je to nešto staro, nešto dosadno, nešto što je bilo tu prije nego što je itko od uključenih inženjera znao pisati kod, i što nitko nije mislio da treba iznova pogledati jer — opet — radilo je. Dvadeset pet godina je impresivan alibi. Samo što alibi nije isto što i zdravlje, a upravo to je nalaz koji ova obdukcija, iz poglavlja u poglavlje, ponavlja s istom hladnom dosljednošću: činjenica da nešto dugo stoji nije dokaz da je čvrsto. Često je dokaz samo da ga još nitko nije dovoljno jako gurnuo.

Nalaz i (ne)pouka
§ 05

Nalaz i (ne)pouka

Vrijeme je za nalaz obdukcije. Uzrok smrti: iluzija da je infrastruktura interneta zdrava, jer nitko nije dijagnosticirao dovoljno pažljivo da vidi kako umire. Formalna dijagnoza glasi ovako: internet je katedrala izgrađena na volonterskim temeljima. Gore su kupole, tornjevi, vitraji — golemi cloud, streaming platforme, banke, države. Dolje, u temeljima, jedan njemački doktorand uoči Nove godine, jedan čovjek koji desetljećima sam održava Bash shell stariji od pada Berlinskog zida, i budžet manji od plaće jednog prosječnog inženjera u Silicijskoj dolini. Ne trebaš biti patolog da vidiš gdje puca prvo.

I nije to bila jednokratna dijagnoza koja se poslije riješila. Godinama kasnije, u Sedmoj knjizi ove kronike, obradili smo Log4Shell — istu bolest, drugi organ. Biblioteka za logiranje (dosadan komad koda čiji je jedini posao bilježiti što se u sustavu događa, da programer poslije ima trag ako nešto pođe po zlu), koju je održavala šačica ljudi bez plaće, iznenada je postala rupa kroz koju je prošla pola korporativne Amerike. Recidiv. Pacijent je bio na intenzivnoj, pustili su ga kući, i vratio se sa istom dijagnozom. Da je ovo bolnica, tužili bismo je za nesavjesno liječenje.

Reakcije su, pravedno rečeno, postojale. Linux Foundation je pokrenula Core Infrastructure Initiative — konzorcij velikih tvrtki koje su, s ponešto zakašnjelom savjesti, odjednom počele bacati novac na projekte koje su godinama koristile besplatno. OpenSSL je dobio sredstva za razvijatelje zaposlene na puno radno vrijeme. Kasnije su se pojavili i tzv. sovereign tech fondovi — državni novac, njemački, pa i drugi, koji tretira održavanje kritičnog open source koda kao pitanje nacionalne infrastrukture, isto kao mostove i ceste, a ne kao dar od nepoznatog čovjeka na internetu. Novac je, konačno, počeo kapati prema temeljima. Rješenja koja smo najavili kao mogućnost u ranijim poglavljima — konačno klinički dokazana, uz račun i potpis.

Samo — i ovo je dio nalaza koji se ne smije preskočiti u zaključku — struktura ispod svega toga novca nije se promijenila. Fondovi gase požare. Ne plaćaju za dosadno čuvanje vatre koja ne gori. Poticaji u cijeloj industriji, od GitHub zvjezdica do developerskih životopisa, nagrađuju novo: novi framework (gotov kostur koda na koji programer samo nadograđuje svoje), novi proizvod, novi launch s balonima. Nitko ne dobiva promociju za to što je tri godine tiho čuvao biblioteku koja šifrira pola svjetskog internetskog prometa. Left-pad, tema jednog ranijeg poglavlja ove knjige, pokazao je istu krhkost na trivijalnom paketu od jedanaest linija koda koji je srušio pola interneta kad ga je autor u bijesu obrisao. Heartbleed je pokazao identičnu krhkost na temeljima civilizacije. Razlika u važnosti pacijenta ne mijenja uzrok smrti. Rima je preciznija nego što bismo htjeli.

I tu dolazimo do poante cijele ove obdukcije, ne samo ove sekcije. Najskuplja infrastruktura civilizacije — ona na kojoj sjedi svaka banka, svaka bolnica, svaka vlada — najčešće je besplatna, i upravo zato zapuštena. Ne zato što je nitko nije htio platiti, nego zato što je nitko nije morao platiti dok je radila. „Zdravlje” koje smo joj pripisivali nikad nije bilo dijagnoza. Bio je to samo izostanak simptoma. Šutnja koju smo protumačili kao mir, a bila je samo tišina prije nego što netko pošalje heartbeat paket i dobije 64 kilobajta tuđih tajni na dar.