ABillionLaughs
20.03.22
En god latter forlenger livet
De aller fleste av oss har hørt uttrykket «En god latter forlenger livet». Jeg har aldri betvilt påstanden. Man kan liksom kjenne at det er godt å le! Selv er jeg en person hvor latteren sitter løst og kan le både i passende og i upassende situasjoner. Forskere mener nå å ha bevis på at en god latter faktisk forlenger livet. En studie fra NTNU med et tidsspenn på 15 år og med 53566 involverte personer viser tydelige tegn. Jeg har forsøkt å skape et sunt og lattermildt miljø i mitt hjem, men foreløpig er tilbakemeldingen at jeg har dårlig humor. Jeg anerkjenner at det må jobbes med.
A Billion Laughs
Hvis én god latter forlenger livet, hva med en milliard lattere?Jeg tviler på at latter var reaksjonen når IT-systemer ble tvunget ned i knestående etter det som i etterkant har blitt døpt til «A billion laughs attack». Dette angrepet faller innunder kategorien «Denial of Service» (DoS) og rettet seg mot programmer som analyserte strukturert tekst som XML og YAML. Angriperne utnytter en sårbarhet i form av å definere en DTD (Document Type Definition) i en XML-fil (v.1.0) og henvise til denne rekursivt.
Jeg synes det er både interessant og viktig å lære hvordan slike angrep fungerer og videre forstå hvilke grep man kan ta for å gjøre systemene sine mer robuste. I denne posten vil jeg forsøke å formidle dette via en liten fortelling.
Spol tilbake til 2003
Forestill deg en online tjeneste som oversetter XML til JSON. Tjenesten er hyppig besøkt av utviklere fra hele verden som har nettopp dette enkle behovet. Eieren av tjenesten er en pensjonert professor ved universitetet. Tjenesten ble skrevet for mange år siden og har krevd svært lite vedlikehold siden. En liten server i boden har fått ansvaret å tilby tjenesten til hele verden. Det er et ansvar den har tatt seriøst og viftene spinner samvittighetsfullt der den er plassert på en liten reol ved siden av printeren. Fra tid til annen setter professoren seg ned foran maskinen med et krus fylt med varm kaffe og undersøker loggene for feil. Det er lenge siden det har oppstått feil nå. Den pensjonerte professoren har som vanlig stått opp tidlig og solen har enda ikke rukket å titte opp fra horisonten. Han har alltid vært glad i disse timene før alle andre våkner. Det er stille og en dis av forventning i lufta. Det er blitt planlagt en spasertur bort til bakeriet for å handle wienerbrød og drikke kaffe denne formiddagen. Professoren, ikledd morgenkåpe, sokker og tøfler åpner loggene og til sin forbauselse ser at tjenesten har gått ned siden sist gang han logget seg på. Ved første øyekast så ser det ut som om noe har forsynt seg grådig av tilgjengelig minne på serveren. Professoren titter mistenkelig bort på serveren og stusser på om den kanskje også burde pensjonere seg.
«Hva er det som skjer? Er det et DDoS-angrep mot nettsiden min?» tenker den nå litt irriterte og stressa professoren. Det er synd fordi stress, i motsetning til latter, er ryktet til å forkorte livet. Et DDoS-angrep (Distributed Denial of Service) er når tusenvis av maskiner sender enorme mengder henvendelser til en server samtidig med et mål om å overbelaste den. Professoren leser kjapt over loggene, men de viser ingen tegn på at det har vært mer trafikk enn vanlig. Snarere tvert imot. De siste årene har det dukket opp like mange identiske XML-til-JSON-tjenester på internett som ugress i veikanten. Professoren ergrer seg over disse nye tjenestene med deres dumme CSS-styling som kaster feilmeldinger i hytt og pine og ikke klarer å oversette de enkleste XML-filer. Tjenesten hans er kanskje av den enklere sorten utseendemessig men den har alltid vært pålitelig og det har han vært stolt over. Professoren finner frem lesebrillene og tar en slurk av kaffen. Alt for varm. «La oss komme til bunns i dette før bakeriene åpner».
Viftene på serveren spinner litt ekstra når professoren åpner loggfilen over siste nettverkshendelser, som for å vise at den også har lyst å bidra til å løse dette mysteriet. Kanskje har den lyst å bevise at det ikke er behov for en oppgradering av maskinvare i boden. Det siste logginnslaget ser ikke så mistenkelig ut. XML-filen som ble lastet opp var jo mindre enn 1 KB. Tjenesten har jo håndtert filer som er mye større enn dette. Professoren leter i flere logger for å se hva rotårsaken til denne uakseptable feilen kan skyldes. I applikasjonsloggen finner han XML-filen som har forårsaket katastrofen. «Hva i alle dager er dette?» mumler professoren lavt og tar en ny slurk med kaffe. Fortsatt alt for varm.
XML-filen som ble sendt inn så slik ut:
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
Professoren retter seg opp i stolen og lener ansiktet litt nærmere skjermen. Innholdet i den korte, men underlige, XML-filen reflekteres i lesebrillene. Hodet kverner for å få et mentalt bilde av hva hensikten med denne filen er. Professoren finner frem en notatblokk og en kulepenn fra skuffen under skrivebordet. Begge to er prydet med universitets logo og har bodd i skuffen i minst fem år. Han tester innholdet i kulepennen og den svarer med å lage en fyldig blå krussedull i hjørnet av en blank side i notatblokken. Kvalitetspenn.
Professoren starter med en systematisk gjennomgang av den kryptiske XML-filen. Han registrerer at det kun er et element i filen, nemlig <lolz>
. Innholdet av dette elementet er &lol9;
. Dette er en referanse til en definert entitet tidligere i XML-filen. Denne entiteten har verdien &lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;
. Ti referanser til entiteten lol8
som igjen er en referanse til en ny entitet. Dette mønsteret fortsetter hele veien til lol1
. «Oi, dette vil eskalere raskt» tenker professoren! «Dette vil resultere i at XML-funksjonen skriver ut verdien av rotelementet 10 opphøyd i 9 ganger. En milliard ganger!». Professoren stirrer tomt på skjermen foran seg. Han forstår ikke hvorfor noen har behov for å skrive en verdi så mange ganger. Det er uansvarlig bruk av datamaskiner! Han titter raskt på innholdet av variablen lol
som er så heldig å ha fått æren for denne kalkuleringen. «lol». Han mener å huske at dette er en forkortelse for Lots of Love. Professoren føler ikke mye kjærlighet nå.
Professoren bruker terminalen til å navigere seg frem til kildekoden. Minner, i form av små glimt, bobler opp til overflaten fra tiden da han arbeidet på universitetet. Det tar noen lange sekunder før han spretter tilbake til nåtiden og åpner filen for XML-leseren i VIM. Prosjektet var opprinnelig et hobbyprosjekt som etterhvert viste seg å være ganske nyttig. Det var derfor han valgte å dele dette som en tjeneste for hele verden. Han er i grunn ganske stolt av hvor godt stukturert kildekoden er og hvor elegant den er skrevet. Det har vært noen år siden han har vært her sist, men det føles som å komme tilbake til barndomshjemmet.
Professoren vet akkurat hvor han skal. Det er en del av kildekoden som håndterer Document Type Definitions. Dette er vanligvis brukt som en form for validering av XML-skjemaet og beskriver strukturen og hva som er tillat som lovlige elementer. Det er denne funksjonaliteten som nå er blitt utnyttet på det groveste. Øynene glir raskt over skjermen i det velkjente terrenget av kildekode før han griper etter kulepennen og notatblokken med den like velkjente logoen. Han skriver ned følgende på samme side som krussedullen:
Mulige løsninger på DTD-misbruk:
- Det er ikke lenger lov å bruke DTD
- Implementere en maksgrense for antall tegn som kan genereres via en entitetreferanse
- Redusere antall entitetnoder som kan evalueres
- Avbryt dersom minnet overstiger en bestemt verdi
Professoren setter en strek over det første alternativet. Han er såpass stolt av denne funksjonaliteten og ønsker ikke at en bølle skal ødelegge for alle andre. Han lener albuen på bordet og ser på alternativ to. Det er mulig å telle antall tegn som blir generert via en entitetsreferanse og avbryte dersom dette overstiger et visst antall. «Hva skal det antallet være? Et hundre tegn? Et tusen tegn?» undrer professoren seg. Øynene glir ned på alternativ tre før de lukkes for å gi rom for hjernen å tenke. Professoren forsøker å huske om han noen gang har opplevd at det har vært nødvendig at en entitet henviser til en annen entitet mer enn akseptabelt mange ganger. Magefølelsen gir et signal om at dette føles riktig. En stødig og bestemt hånd sirkler rundt alternativ nummer tre. Han tenker at dette alternativet vil stoppe slike uansvarlige angrep og likevel sørge for at de som bruker XML-standarden forsvarlig kan bruke tjenesten. Professoren vet akkurat hva han må gjøre.
Det er lenge siden professoren har programmert og mens han satt der i morgenkåpen kjente han på den gode følelsen som oppstår når man gjør seg flid med arbeidet. Det er som om arbeidet omfavner ham og alle andre inntrykk blir skjøvet til side. Som en erfaren pianist med innøvd muskelminne glir fingrene erfarent over tastaturet og spiller sin egen velkjente melodi. Etter en liten stund, som for å fortelle publikum at verket er ferdig, så stopper all lyd opp før fingrene spiller en siste tone: Enter-knappen, hardt og bestemt. Professoren setter seg tilbake i stolen og kjenner på stivheten i ryggen. Han ble nok litt for ivrig foran tastaturet. Det er fort glemt når konsollen gledelig viser at alle testene har passert. «Glimrende! Nå skal det godt gjøres å overbelaste tjenesten min» tenker professoren og ser raskt bort på serveren som spinner litt ekstra med viftene, fornøyd. Noen øyeblikk senere er tjenesten oppe å går igjen med et enda mer robust rammeverk. Professoren er svært fornøyd med innsatsen disse morgentimene. Han legger plutselig merke til at det har dukket opp et gjenskinn i skjermen og registrerer at solen også har stått opp. Han ser raskt på klokken og merket seg at han fremdeles har litt tid før de skal spasere til bakeren. Magen rumler i forventning til et ferskt wienerbrød. Han griper etter kruset med kaffen og tar en god slurk. Iskald.