Det har nå gått litt over en måned siden det ble publisert en sårbarhet i Apache Log4j-rammeverket. Sårbarheten, som går under kallenavnet Log4Shell, ble utnyttet ganske raskt, og mange virksomheter, både her i Norge og i resten av verden, måtte stenge ned en stund. Noen ble faktisk angrepet, mens andre trengte tid for å få på plass tiltak mot sårbarheten. Men nå som støvet har lagt seg litt, kan vi stille oss spørsmålet om hva vi har lært av denne hendelsen.
Datatrafikk: Filtrer både på vei inn og på vei ut
Første lærdom er at det er viktig å ha kontroll på datatrafikk, både på vei inn og på vei ut. Det er fort gjort å tenke at siden angrep kommer utenfra, er det først og fremst datatrafikk på vei inn det er viktig å scanne og filtrere for å unngå problemer. Men for det første kan truslene også sitte på innsiden av organisasjonen – utro tjenere for å nevne et åpenbart eksempel – og for det andre kan tilsynelatende legitime datastrømmer på vei inn forårsake illegitim datatrafikk ut.
I dette tilfellet kunne en del virksomheter beskytte seg mot Log4Shell-angrepet på en effektiv måte ved å legge til passende regler i WAF-produktet (web application firewall) de brukte. I tillegg måtte de selvfølgelig også oppdatere Apache Log4j-biblioteket der det var brukt, men som et første tiltak kunne man i mellomtiden i hvert fall opprettholde systemene ved å ha kontroll over datatrafikk på vei ut.
Oppdaterbar er bedre enn oppdatert
Dermed har vi allerede kommet litt borti andre lærdom fra Log4Shell-hendelsen: Det er viktig å være i stand til å oppdatere biblioteker med sårbarheter i løpet av kort tid. Spesielt har vi lært at det er viktigere å ha programvare og komponenter som er oppdaterbare enn at de er oppdatert.
Det sier seg selv at du stiller som regel bedre med oppdaterte komponenter enn med utdaterte komponenter, også når det gjelder oppdaterbarhet. Men en litt utdatert komponent som man på en grei måte kan oppdatere til nyeste versjon, og mulighet til å sette den og resten av programvaren i produksjon i løpet av kort tid, er bedre enn en oppdatert komponent som så trenger en seks ukers testperiode. Et godt byggemiljø med fungerende CI/CD-pipelines for kontinuerlig leveranse, inkludert automatiserte akseptansetester som reduserer behovet for mye manuell regresjonstesting, er gull verdt i slike situasjoner.
Avhengigheter, direkte og indirekte
Men hvordan vet man hvilke komponenter man skal oppdatere? Her kommer tredje lærdom fra Log4Shell: Det er viktig å ha en oversikt over alle avhengighetene i programvaren din. Dette gjelder ikke bare direkte avhengigheter, det vil si bibliotekene du har lagt til selv, men også indirekte, det vil si bibliotekene som bibliotekene du har lagt, til støtter seg på. I den forbindelse er det også viktig å huske på at samme bibliotek kan være inkludert i programvaren gjennom flere komponenter, og til og med i forskjellige versjoner.
Dette er særlig relevant for et loggrammeverk som Apache Log4j, som har eksistert lenge og har blitt brukt i mange andre biblioteker. En slik fullstendig oversikt, som ikke bare inneholder hvilke biblioteker som har blitt brukt, men også alle versjonsnumrene, kaller man gjerne en software bill of materials (SBOM). Men å ha en fullstendig oversikt er én sak, å kunne trekke riktig informasjon ut av den er en annen. Og enda bedre er det selvfølgelig om man kan stille en slik oversikt målrettede spørsmål. At oversikten må være levende og oppdatert (eller raskt oppdaterbar), tar vi for gitt.
Hele stacken må scannes
Fjerde lærdom er at det er viktig å ha verktøy på plass som kan scanne alle komponenter som er i bruk i produksjonsmiljøet. Dette gjelder ikke bare komponentene du har brukt for å utvikle programvaren din, men også komponentene som programvaren din kjører på. Selv om koden du har utviklet, bygget og rullet ut, er til å stole på, kan det fremdeles være sårbarheter i containerne koden din kjører på.
Her er det også viktig at man ikke bare scanner stacken idet man setter et system i produksjon, men scanner den om igjen etter hvert som det blir oppdaget nye sårbarheter. Det hjelper lite at du har ryddet bort gamle versjoner av Apache Log4j fra programvaren din hvis Kubernetes-imaget fremdeles er sårbart for Log4Shell. Aqua Security, som Computas er partner med, er et eksempel på et verktøy som gjør en slik scanning. Selv har Aqua Security skrevet en liten bloggartikkel om Log4Shell og hvordan deres produkt kan være behjelpelig med å beskytte seg mot eventuelle angrep.
Kodepatterns
Og til slutt, så er vår femte lærdom at statisk kodeanalyse er et helt nødvendig verktøy når man utvikler programvare. Denne gangen var man så heldig at det fantes enkle, raske løsninger som WAF, som kunne kjøpe nødvendig tid til å oppgradere Apache Log4j til nyeste versjon, men det vil ikke alltid og overalt være mulig.
Da er det viktig at man har verktøy tilgjengelig som kan gå inn i koden og finne ut hvor sårbare biblioteker har blitt brukt, ikke bare som avhengigheter, men også de faktiske kodekallene som man selv har lagt inn. Selv om man da sannsynligvis ikke kan gjøre noe med kallene utført i avhengigheter, kan man i hvert fall begrense og vurdere egen bruk av sårbare biblioteker. Det må legges til at Computas generelt har lang og god erfaring med bruk av statisk kodeanalyse, og at vi anbefaler alle våre kunder å bruke verktøy som for eksempel SonarQube for å holde oversikt over kodekvalitet.
Bonus: Hva var ikke problemet?
Det er kanskje ikke helt en lærdom, men likevel verdt å nevne hva som ikke var problemet med Log4Shell. I begynnelsen av Log4Shell-hendelsen var det noen personer her og der som pekte på Java som grunnproblemet, eller bruk av open source-software. Det var det selvfølgelig ikke. Heller ikke Apache Log4j var problemet, selv om det var kasuset i dette tilfellet.
Man kan også si mye om vurderingen av å bygge inn JNDI-oppslag i et loggrammeverk, særlig i etterpåklokskapens lys. Men også andre loggrammeverk, både i Java og andre programmeringsspråk, og rammeverk til andre formål generelt, har hatt og kommer til å ha sine sikkerhetsproblemer. Det viktige er å være klar over at slike problemer kan bli oppdaget og utnyttet når som helst – også rett før juleferien– og at man da må kunne reagere raskt. Å ha de riktige verktøyene, riktig arkitektur og riktig metodikk på plass er derfor alfa og omega for å kunne overleve i dagens IT-verden.