In English

Säkerhetstest • Artikel

4 maj, 2021

Vad innebär en säkerhets­granskning av källkod?

En säkerhetsgranskning av källkod innebär att någon granskar källkoden ur ett säkerhetsperspektiv. Men vad innebär metoden, och vilka är för- och nackdelarna med att säkerhetsgranska källkod? Här försöker vi reda ut frågorna.

Säkerhetsgranskning av källkod vs. källkodsgranskning

En applikation kan säkerhetsgranskas på en mängd olika sätt; dels med sårbarhetsskanning och penetrationstester, med hjälp av risk- eller hotbildsanalyser, eller genom så kallad källkodsgranskning, där källkoden granskas direkt.

Säkerhetsgranskning av källkod

Säkerhetsgranskning av källkod genomförs med syfte att upptäcka eventuella säkerhetsbrister. Genom att ha direkt tillgång till källkoden är det möjligt att följa det flöde en applikation och dess data tar, för att på så sätt upptäcka dold eller alternativ funktionalitet som kan leda till säkerhetsbrister. En säkerhetsgranskning av källkoden kan på så sätt uppmärksamma brister som inte går, eller åtminstone är ytterst svåra att upptäcka med andra typer av säkerhetsgranskningar.

Källkodsgranskning

Källkod kan granskas av flera anledningar, och inte enbart ur ett säkerhetsperspektiv. Att granska varandras källkod i en utvecklingsgrupp kan till exempel tidigt upptäcka buggar eller felaktiga implementationer, samt leda till att kännedom om källkoden sprids inom gruppen. Granskningen kan även ha som syfte att öka prestandan eller optimera kod, se till att dokumentation är uppdaterad och korrekt, eller att koden följer en överenskommen kodstandard.

På samma sätt som att det finns flera alternativa sätt att säkerhetsgranska applikationer, finns det också olika sätt att säkerhetsgranska källkod. Nedan tittar vi närmare på några av de vanligaste tillvägagångssätten och vad de innebär.

Olika typer av källkodsgranskning

På samma sätt som att det finns flera alternativa sätt att säkerhetsgranska applikationer, finns det också olika sätt att säkerhetsgranska källkod. Nedan tittar vi närmare på några av de vanligaste tillvägagångssätten och vad de innebär.

Fuzzning

Fuzzning är en typ av granskning där en körande applikation testas med slumpmässig indata, i syfte att hitta brister som kan uppstå när applikationen hanterar oväntad data. Det främsta användningsområdet för fuzzning är att hitta buffertöverskridningar eller deserialiseringsbuggar. 

I praktiken matar en fuzzningsmotor en applikation med slumpad data och upptäcker när applikationen kraschar. Fuzzningen kan med lätthet automatiseras, men varje funnen krasch bör granskas manuellt. 

Ett exempel på en känd sårbarhet som har upptäckts med hjälp av fuzzning är Heartbleed, som år 2014 påverkade en stor mängd sevrar på internet. 

Automatiska verktyg

Det finns flertalet verktyg som utlovar att hitta säkerhetsbrister i en applikation; dels verktyg som enbart granskar källkoden, men även andra typer av verktyg som behöver applikationen i olika former av exekverbar form. Gemensamt för alla är att de är begränsade till signaturer som främst hittar generella brister i applikationen och har svårt att identifiera brister i applikationens affärslogik. Signaturerna är oftast kodspecifika, där samma verktyg har svårt att granska applikationer i flera kodspråk.

Manuell granskning

Manuell granskning är helt klart den mest tidskrävande, men också den mest grundliga formen av granskning. Manuell granskning innebär att en eller flera personer går igenom kodbasen manuellt, med eller utan verktyg som stöd. Vi på Sentor rekommenderar ofta företag att tillämpa en blandning av automatisk och manuell granskning, där en granskare går igenom källkoden med hjälp av verktyg.

För- och nackdelar med att säkerhetsgranska källkod

Som med alla former av säkerhetsgranskningar är den största fördelen uppenbar - säkerhetsbrister och sårbarheter uppdagas och kan åtgärdas, förhoppningsvis innan en angripare hinner utnyttja dem. Men det finns även fler fördelar med att låta någon säkerhetsgranska källkoden innan den går till produktion;

Fördelar med att säkerhetsgranska källkod

En av fördelarna med att granska källkoden framför andra typer av säkerhetsgranskningar är att underliggande sårbarheter kan upptäckas. Mer specifikt kan det röra sig om komplicerade sårbarheter som inte alltid är direkt exponerade mot en angripare, eller sårbarheter som bara uppkommer under speciella omständigheter. Även om det underlättar att ha en körandes applikation så är det inget krav för att granska källkoden, vilket medför att man man redan i utvecklingsskedet kan granska koden och tidigt upptäcka och åtgärda säkerhetsbrister. 

Det är även lättare att finna systematiska eller strukturella misstag som begås av utvecklarna, och på så sätt utbilda dem för att ytterligare stärka säkerheten både direkt och i framtida projekt. En granskare med tillgång till källkoden kan även ge bättre rekommendationer och råd till utvecklare för att åtgärda bristerna. 

Sist men inte minst är det betydligt billigare och enklare att åtgärda en säkerhetsbrist redan under utvecklingsprocessen, istället för att behöva reparera skadan i efterhand.

Nackdelar med att säkerhetsgranska källkod

Trots att säkerhetshetsgranskning av källkod är ett effektivt verktyg för att hitta brister, är det i många fall även väldigt tidsödande, speciellt i de fall då en stor applikation granskas för första gången. Om granskaren inte har tillgång till en körande applikation kan det även vara svårt att granska applikationen med hänsyn till andra tillhörande applikationer, eller verifiera ifall en brist verkligen går att utnyttja. 

Vad kan man hitta genom att säkerhetsgranska källkod?

Följande är exempel på säkerhetsbrister som kan hittas vid en källkodsgranskning. Samtliga är brister som även kan hittas med annan form av säkerhetsgranskning, om än mycket svårare.

Buffertöverskridning

Buffertöverskridning eller buffertspill (kanske mer känt som buffer overflow) uppstår när en applikation försöker skriva till en minnesrymd som är utanför dess allokerade buffer. Traditionellt sett är detta en mycket allvarlig säkerhetsbrist, då den kan leda till att en angripare att köra sin egen kod i applikationen. Vid en statisk kodanalys kan man snabbt identifiera potentiella sårbara funktioner som behöver granskas noggrannare. Även fuzzning kan användas för att hitta buffertöverskridningar och liknande brister.

Kryptografiska sårbarheter

Brister i kryptografiska funktioner kan leda till kritiska sårbarheter i en applikation, såsom möjlighet att kringgå autentisering- eller behörighetskontroller, samt läckage eller modifiering av känslig data. Genom att granska källkoden är det möjligt att härleda vilka kryptografiska lösningar som används, samt ifall dessa är korrekt konfigurerade.

Hårdkodade inloggningsuppgifter

Det är vanligt att applikationer har kopplingar till underliggande system. I de fall då dessa sker via osäkra metoder behöver de dokumenteras och bytas ut. Det kan till exempel vara användarnamn och lösenord eller tokens som finns hårdkodade direkt i källkoden, eller som lagras osäkert i konfigurationsfiler. Om applikationen hanterar sig egen autentisering är det av yttersta vikt att det verifieras att detta sker korrekt. I vissa fall lägger utvecklare in hårdkodade uppgifter för att kringgå inloggningar för att underlätta utveckling. Om dessa finns kvar vid produktionssättning kan det få förödande konsekvenser. I vissa fall, om än ovanliga, har en angripare lagt in en så kallad bakdörr som kan utnyttjas för att kringgå autentisering.

Alternativ funktionalitet

Genom att granska källkoden är det lätt att upptäcka alternativ funktionalitet som inte skulle ha upptäckts annars. Det kan till exempel handla om gammal funktionalitet som tagits ur bruk och inte uppdaterats, men inte tagits bort i källkoden. Vissa funktioner kanske tar extra parametrar, vilket ändrar exekveringsflödet med oväntade resultat. Underliggande eller komplexa brister, såsom race conditions eller TOCTOU (time-of-check to time-of-use), är också lättare att hitta i de fall man kan följa flödet i koden. Det kan även handla om tredjepartsberoenden där bara en liten del av funktionaliteten används av applikationen, men en större del ändå exponeras utåt.

Sårbara bibliotek

Många applikationer har idag beroenden till tredjepartskod, det vill säga komponenter utvecklade av tredje part som inkluderas i applikationen för att utöka funktionaliteten. Generellt är detta bra, då utvecklare slipper uppfinna hjulet på nytt, förutsatt att utvecklarna väljer ett bibliotek som underhålls och som även genomgått säkerhetsgranskningar. Problem kan däremot uppstå när säkerhetsbrister upptäckts i biblioteken, vilket implicit introducerar säkerhetsbrister i själva applikationen. Genom att säkerhetsgranska källkoden kan alla bibliotek listas och kontrolleras om huruvida de innehåller kända sårbarheter. Det är även möjligt att verifiera att biblioteken är korrekt integrerade och konfigurerade.

Kodstandard och mognadsgrad

En säkerhetsgranskning av källkoden kan även ge svar på om utvecklarna tycks vara medvetna om de eventuella säkerhetsbristerna deras kod kan leda till, samt om de använder säkra eller osäkra funktionsval när de utvecklar. Det kan även ge organisationen svar på ifall utvecklarna behöver mer utbildning, alternativt stöd i utvecklingen för att säkerställa säkerheten i applikationerna.

Verktyg

Det finns ett antal verktyg på marknaden som utlovar att genomföra automatisk källkodsgranskning. Man kan dels använda klassiska kodgranskningsverktyg, såsom SonarQube, ESLint och FindBugs, då många av de innehåller regler för att hitta de vanligaste säkerhetsbristerna. Det finns även verktyg som är specifikt inriktade på säkerhetsgranskningar av källkod (på engelska kallad Static Application Security Testing, eller SAST) såsom Checkmarx, Coverity och Veracode. Gemensamt för alla dessa verktyg är att de tenderar att generera en stor mängd resultat - resultat som i sin tur behöver granskas manuellt av en kunnig granskare.

Så kan vi hjälpa dig

Vi på Sentor utför en mängd källkodsgranskningar för våra kunders räkning; både i form av kontinuerliga granskningar, där våra experter sitter som en resurs till utvecklarna, men även som engångsuppdrag där vi granskar källkod och överlämnar en rapport vid uppdragets slut.

Vi uppmanar alltid våra kunder att genomföra så kallade white-box-tester när vi genomför granskningar. Detta innebär bland annat att källkod eller annan dokumentation tillgängliggörs till granskarna vid ett uppdrag, till exempel vid ett penetrationstest. En granskare kan då direkt härleda sårbarheter i källkoden och tillhandahålla bättre rekommendationer.

Läs mer om vår kodgranskningstjänst, eller hör av dig om du vill veta mer om hur vi kan hjälpa dig!