Hopp til innhold
Tjeneste, prosjekt, navn...

Kontakt oss

Slik sikrer du dine Python-leveranser

Digi.no publiserte nylig en artikkel om en femten år gammel sårbarhet i et Python standardbibliotek. Sårbarheten kan kompromittere infrastruktur over hele verden. Det er alvorlig, men kan løses enkelt: Ikke støtt arkiv-formater, med mindre du virkelig må. 

Av: Stig M. Baugstø, seniorkonsulent hos Webstep.

IT-sikkerhetsfirmaet Trellix har gjenoppdaget sårbarheten fra 2007, kjent som CVE-2007-4559, og har gjennom sin artikkel demonstrert hvordan sårbarheten kan utnyttes, og hvilke katastrofale følger dent kan gi. Dette har kastet nytt lys over saken, og ført til medieoppmerksomhet de siste dagene.

Og om det ikke var ille nok, så har ikke de som vedlikeholder Python noen planer om å korrigere sårbarheten. De har heller publisert en advarsel i dokumentasjonen om å ikke pakke ut arkiv fra upålitelige kilder uten å gjøre en grundig undersøkelse av innholdet først; Ansvaret legges med andre ord på utviklerne.

Skjermbilde fra en advarsel som sier: Never extract archives from untrusted sources withouth prior inspection. It is possible that files are created outside of path, e.g. members that have absolute filenames starting with / or filenames with two dots . .

Skjermbilde av advarselen i Pythons offisielle dokumentasjon for det sårbare biblioteket (2023-09-23).

Problemet er at såkalte tar-arkiv (alternativ til zip-arkiv) kan inneholde vilkårlige filstier, som kan føre til overskriving av viktige filer når arkivet pakkes ut. Sårbarheten ligger eventuelt i Python-kode som pakker ut et slikt arkiv. Det kan i verste tilfelle medføre at en trusselaktør kan ta over hele miljøet som en sårbar applikasjon kjører på.

Så hvordan i all verden skal du vite om du er påvirket, og hvordan beskytter du deg? Dette innlegget forsøker å svare på det.

Er jeg påvirket av sårbarheten?

Først må du ha oversikt. Fra et sikkerhetsperspektiv, så skal du ideelt sett allerede ha full oversikt over alle dine kjørende applikasjoner, aktiv kode og tredjepartsavhengigheter. Men for de fleste er nok verden litt annerledes.

Først og fremst må du vite om noen av dine systemer eller applikasjoner er skrevet i Python. Om du med høy sikkerhet kan svare nei på spørsmålet, så er du sannsynligvis allerede i mål. Om svaret er ja, eller du er usikker, så må du grave videre.

Neste spørsmål man kan stille seg er hvorvidt man vet om noen av disse systemene eller applikasjonene støtter filopplasting av tar-arkiv. Og om man vet om at disse arkivene blir pakket ut med kode. Om svaret her er helt klart nei, så er du sannsynligvis trygg, men det er bedre å være på den sikre siden og undersøke litt videre.

Om du sitter på kodebasen til de aktuelle programmene, så kan du selv gjøre en enkel sjekk ved å søke etter bruk av den sårbare extractall-funksjonen i kildekoden. Finner du den ikke, så bør det vel ikke være noe problem, eller? Nei. Problemet er tredjepartsavhengigheter, altså kodebiblioteker og ferdig kode fra tredjeparter som du bruker i løsningen. Om du vet hvor disse er lagret, så kan du også søke igjennom de etter den sårbare funksjonen. Men det er lett å tråkke feil med slike manuelle prosesser.

Trellix som nylig omtalte saken har utviklet et verktøy kalt Creosote, et script som kan brukes til å søke gjennom kildekoden for deg. Verktøyet finnes på GitHub. Om du benytter Creosote kan du forhåpentligvis raskt få svar på hvorvidt din applikasjon er påvirket av sårbarheten. Men, vær forsiktig! Selv om jeg etter en rask gjennomlesning nå ikke finner noe ondsinnet kode i verktøyet, så kan kildekoden til verktøyet når som helst endres. Man skal alltid selv lese igjennom kildekoden og vurdere risikoen av verktøy før man kjører dem; Det er kjedelig å bli hacket av et verktøy. Forhåpentligvis vil deteksjon av den sårbare funksjonen bli implementert i mer anerkjente verktøy som f.eks. Trivy eller Snyk. Selv kunne jeg tenkt meg at Python selv ga en advarsel om man bruker funksjonen.

Finner du den sårbare funksjonen i kildekoden og du vet at den er i bruk, så bør du iverksette tiltak for å forhindre utnyttelse av sårbarheten.

Men hva om det ikke er din kode, eller er en applikasjon skrevet av noen andre? Da bør du ta kontakt med de ansvarlige for applikasjonen og høre hvordan de forholder seg til sårbarheten. Henvis gjerne til denne artikkelen.

Til orientering finnes den offisielle advarselen kun i dokumentasjonen til Python 3, men merk at sårbarheten først ble oppdaget da Python 2 var gjeldende og innehar sannsynligvis samme sårbarhet. Merk at Python 2 ikke lengre er støttet og ikke har fått sikkerhetsoppdateringer siden 2020; Det anbefales ikke å bruke.

Hvordan beskytte seg mot sårbarheten?

Utviklerne bak Python vil som nevnt ikke korrigere sårbarheten, så hvordan beskytter man seg?

En god start kan være å lese og sette seg inn i OWASP sine anbefalinger for håndtering av filopplastning og filer fra upålitelige kilder, dokumentert i OWASPs file upload cheat sheet; En ressurs jeg mener alle utviklere som håndterer filer bør sette seg inn i. Et viktig punkt fra siden som jeg siterer her er:

“ZIP files are not recommended since they can contain all types of files, and the attack vectors pertaining to them are numerous.” – OWASP file upload cheat sheet.

Sitatet påpeker zip-arkiv, men er det noe denne sårbarheten har bevist, så er det at det gjelder alle arkiv-formater, inkludert tar. Basert på innholdet i sitatet bør du stille deg følgende spørsmål:

– Trenger vi å støtte opplastning av arkivfiler (tar, zip, rar, etc.)?
– Trenger vi å støtte utpakking av arkivfiler?

Om du er usikker eller kan svare nei på spørsmålene, så kan du enkelt fjerne hele sårbarheten ved å fjerne bruken av det sårbare biblioteket. Ikke bruk det om du ikke må, enkelt og greit.

Men det er sannsynligvis scenarioer der du er nødt til å svare ja på disse spørsmålene, og da er du nødt til å gjøre som advarselen i Python-dokumentasjonen sier: Inspiser innholdet i arkivet før du pakker det ut. Men hvordan gjør man det?

Det finnes to forslag i diskusjonen av sårbarheten i Pythons egen bug tracker. Det ene forslaget kommer fra Kasimir Schulz hos Trellix, men ble raskt avdekket som ikke godt nok. Et annet forslag fra vedkommende som opprettet diskusjonen forhindrer utpakking av filer som begynner med absolutt filsti (/ – root) eller som starter med referanse til ovenstående mappe (../). Selv synes jeg også denne virker for enkel, og jeg er usikker på hvor godt de vil fungere i et Windows-miljø.

Så det er ikke enkelt. Men basert på advarselen i dokumentasjonen bør man lage et filter som ikke tillater filer som peker på roten av filsystemet eller som overhodet inneholder dobbelt punktum. Følger man OWASP sine anbefalinger for input-validering er kanskje en allow list (“hviteliste”) over tillatte tegn i filstiene en god vei å gå, men sørg for å ikke tillatte doble punktum eller filer som peker på roten av filsystemet.

Etter du har implementert kode-endringene er det viktig at det testes skikkelig, slik at du er sikker på at du klarer å forhindrer sårbarheten. Du kan bruke eksemplene fra Trellix sitt blogginnlegg og kombiner dem gjerne med bypass-forslag fra PayloadAllTheThings. For ekstra sikkerhet kan du også implementere testene som en del av din CI/CD-rutine (DevOps).

Øvrig bør du implementere sikkerhetsmekanismer som begrenser skadeomfanget om uhellet først er ute. En god start er å sørge for å kjøre Python-programmene som en svært begrenset bruker, som ikke har flere rettigheter enn nødvendig; Det er vanskelig å skrive over filer man ikke har rettigheter til å røre. Å begrense rettigheter er uansett lurt, uavhengig av sårbarheten eller hvilken teknologi din programvare er skrevet i. Du kan også gjerne kjøre deler av eller hele programmet eller filhåndteringsfunksjonene i et begrenset sandboxed miljø, f.eks. ved bruk av virtualisering.

Videre er overvåkning og varsling viktig, og det lønner seg å ha en plan for hva man gjør når noe går galt. Det er også viktig å ha god kontroll på sine tredjepartsavhengigheter; overvåkning av disse og varsling ved sikkerhetsproblemer bør automatiseres. OWASP har en egen artikkel med anbefalinger for dette.

Hvorfor fikser ikke Python sårbarheten?

Det handler om plassering av ansvar. Finnes sårbarheten i måten Python pakker ut tar-arkiv på, eller er det egentlige problemet at tar-arkiv støtter vilkårlige filstier? Jeg tror ikke det finnes noen klar fasit.

I 2007 valgte utviklerne av Python å ikke anerkjenne problemet som en sårbarhet i Python, og etter min forståelse er det fremdeles deres standpunkt. For alt jeg vet er også støtte for vilkårlige filstier en ønsket funksjon i tar-formatet, og denne ønskede funksjonaliteten vil forsvinne om det fjernes som en sikkerhetsfiks i enten filformatet eller Python. Dermed havner ansvaret på brukeren, som i praksis betyr utvikleren.

Siden problemet strengt tatt ikke ligger i Python, men i filformatet, så finnes det antageligvis tilsvarende sårbarheter i andre programmeringsspråk og for andre filformater enn tar. Det viktigste sikkerhetsrådet om sårbarheten er derfor enkelt å gi: Ikke støtt arkiv-formater, med mindre du virkelig må.

Stig M. Baugstø

– Det viktigste sikkerhetsrådet om Python-sårbarheten er enkelt å gi: Ikke støtt arkiv-formater, med mindre du virkelig må, sier Stig Baugstø, seniorkonsulet hos Webstep.

Relatert / Kontaktpersoner