Detta är det tredje avsnittet i en serie artiklar om den vanligaste typen av attacker mot programvaruleveranskedjan: de som missbrukar ett offentligt register över öppen källkod programvarukomponenter. Efter att ha analyserat i föregående avsnitt "Anatomin hos skadliga paket: Vilka är trenderna?”hur de ondskefulla aktörerna injicerar skadligt beteende i nya eller befintliga publicerade komponenter, är vi redo att ta på oss våra släckvästar och undersöka hur vi framgångsrikt kan blockera skadlig programvara som levereras på detta sätt, eller alternativt hantera en potentiellt allvarlig cyberincident på grund av att vi valt fel tillvägagångssätt.”
De flesta säkerhetsmedvetna yrkesverksamma har idéer om hur man ska hantera detta hot. Vi har hört säkerhetschefer utan tvekan säga att SCA Verktygen berättar redan när en paketversion är skadlig kod. Eller att de är beroende av välkända, mycket granskade programvarukomponenter, där all skadlig kod omedelbart skulle upptäckas och tas bort. De använder öppna mindre/patchversioner för att automatiskt få sårbarhetsåtgärder, och det är det korrekta, rekommenderade sättet att minska risken för beroenden av öppen källkod, enligt "lappa tidigt, lappa ofta”Princip.
I det här avsnittet kommer vi att granska varför dessa idéer är felaktiga, och hur sådana missuppfattningar bidrar till populariteten hos denna attackmekanism, och till en överväldigande risk som organisationer upplever. Vi avslutar med vad som fungerar, och vilka ansträngningar och resurser som krävs.
Vanliga missuppfattningar
Under vår resa med programvarusäkerhet såg vi hur attackteknikerna utvecklades och ett brett spektrum av idéer från säkerhetsmedvetna personer. Organisationer missförstår ofta vad som fungerar mot detta hot, så först ska vi undersöka vad som inte fungerar, sammanfattat i följande, inte uttömmande, lista över missuppfattningar.
Missuppfattning #1: SCA verktyg rapporterar redan skadliga komponenter
Verkligen! Men efter det faktum... När det förmodligen är för sent om elementet användes i en mjukvaruutveckling, och de onda aktörerna redan har fått fotfäste hos en utvecklare eller CI/CD värd. Hemligheter kan ha exfiltrerats, ytterligare skadlig kod kan ha laddats ner och installerats, och kanske har angriparen rört sig i sidled och redan fått åtkomst någon annanstans.
Analys av programvarukomposition (SCA)-verktyg utformades för att identifiera potentiella kända sårbarheter. Moderna verktyg gör ett utmärkt jobb genom att öka signal-brusförhållandet och avgöra om sårbarheten faktiskt är nåbar eller utnyttjad. Men de är värdelösa mot ny skadlig kod. Tänk på en skadlig komponent som en nolldagssårbarhet: Först när dess skadliga beteende upptäcks rapporteras komponenten till det förvarande registret, som efter en granskning av ett säkerhetsteam bekräftas som skadlig och tas bort från registret. [1].
Vid den tidpunkten, världen (inklusive SCAs) vet att det inte är bra att installera eller använda komponenten (eller någon version(er) av en befintlig komponent). Men detta är fallet när komponenten inte är tillgänglig från registret.Att veta att jag har sårbarheter i tredjepartskomponenter, eller till och med komponenter som kategoriserats som skadliga av registret är bra, men tyvärr SCA eller vanliga revisionsverktyg hjälper inte i detta sammanhang. Om inte SCA/audit-verktyget kan verkligen veta i förväg att en komponent är skadlig innan den används i din organisation.
Kom ihåg att alla lösningar mot skadliga komponenter med öppen källkod måste upptäcka dem i farten, mellan när komponenten publiceras i registret och när komponenten (versionen) används för första gången i din organisation. Och det inkluderar transitiva komponenter.
Missuppfattning nr 2: Att kontrollera installationsskript vid byggtid förhindrar skadligt beteende från komponenter med öppen källkod
Olika pakethanterare erbjuder möjligheten att köra skript (ingår i komponenten tarball [2]), av legitima skäl, såsom att kompilera nödvändiga objekt på olika plattformar, generera kod eller köra tester, och vi borde alla veta att de kan missbrukas av dåliga aktörer om skadliga skript inkluderas i tarballen, eller om angriparen kan få ett skadligt skript att köras istället för det bra.
Med tanke på detta kan vi konfigurera pakethanteraren så att den ignorerar skript. Till exempel, med NPM --ignorera-skript flagga (eller en konfigurationsegenskap i .npmrc fil) hoppar över skripten under installationen. Detta kan orsaka vissa problem eftersom det är vanligt att köra skript i många ekosystem: Vissa pakethanterare tillåter inte ens att skriptkörning inaktiveras (ledtråd: prompt “Vilka pakethanterare tillåter inte inaktivering av körning av installationsskript?” i din favorit-AI). Men detta skyddar inte generellt (vi måste se till att konfigurationen för att inaktivera överhoppning är överallt).
Och när det skadliga beteendet inte finns i installationsskript utan i programvaran som ska köras vid körning, skyddar inte detta alternativ oss ensamt.
Missuppfattning nr 3: Versionslåsning förhindrar att skadliga komponenter installeras
Det finns en avvägning mellan att patcha tidigt och att göra det ofta med öppna versioner (låter pakethanteraren automatiskt installera nya uppdateringar när de är tillgängliga för säkerhetskorrigeringar) och versionsfästning (har alla direkta och transitiva beroenden för en programvara i en fast version). Säkerhetsprinciperna är envisa och ibland motsägelsefulla, som händer med "patcha tidigt, patcha ofta" och "Uppgradering ska inte tas lättvindigt"Vissa pakethanterare gör automatiska uppdateringar med serverintervall på det rekommenderade sättet. Perfekt om du också vill ta emot skadliga uppdateringar! Ja, komponenter måste uppdateras för att ta emot säkerhetskorrigeringar som stänger sårbarheter så snart som möjligt, men ... låt aldrig pakethanteraren göra detta automatiskt.
Missuppfattning nr 4: Att använda betrodda komponenter är säkert. Alla skadliga versioner skulle omedelbart hittas, avslöjas och tas bort.
Varför är en komponent betrodd? Möjligen för att den är mycket populär, med många ögon som letar efter sårbarheter, ett stort antal bidragsgivare till underhåll, med flera kärnansvariga som noggrant granskar alla pull requestsVerkligheten är helt annorlunda. Vissa viktiga komponenter underhålls av en enda, obetald utvecklare. Vanligt förekommande ramverk har några regelbundna bidragsgivare, med ett snabbt minskande antal commits per underhållare (populära projekt har en lång svans av bidragsgivare som utför en del drive-by commit och aldrig komma tillbaka). Och populära projekt med en enda underhållare finns i överflöd.
Tänk dig att du säger "Åh, vi använder Spring Boot / Angular / React / PyTorch / officiella Docker-basavbildningar, så risken du pratar om är ganska låg." Kanske är det sant, vi säkerhetsleverantörer som skräms med skrämselpropaganda hela tiden och lägger oss i utvecklingsteam för att mildra en diskutabel risk är nonsens. Du kanske frestas att hoppa till stycket om riskacceptans (i nästa avsnitt) och vara klar. Tyvärr är de mest populära komponenterna måltavlor för dåliga aktörer, och till exempel de populära PyTorch-biblioteket attackerades förr.
"Omedelbart upphittad, avslöjad och borttagen". Det tar dagar för en ny skadlig komponent att tas bort från det offentliga registret. Register är försiktiga med att ta bort en komponentversion, för det bättre. Vår erfarenhet är att när den väl rapporterats från vår sida är mediantiden för registret att ta bort den berörda versionen 39 timmar, mer än en och en halv dag. Det finns skadliga komponenter som tas bort en vecka efter vår första rapportering i registret. Och i vissa fall tas komponenten bort först efter att ett offer eller ett incidenthanteringsföretag rapporterar en incident som involverar komponenten.
Vad som INTE fungerar mot skadliga komponenter
Varje ospecifik metod kommer att misslyckas fatalt. Detta är en självklarhet, du tillhandahåller inte effektiva motåtgärder för den risk som är förknippad med detta hot.
Traditionell SCA Verktygen berättar om känd skadlig kod men har ett stort exponeringsfönster. Om de inte proaktivt utför detektering av skadlig kod med tvångsblockering av skadliga komponenter, fungerar de inte mot detta hot.
Att inaktivera installationsskript kan hjälpa men måste tillämpas överallt där en komponent behöver installeras. Samma sak gäller versionslåsning, eftersom versioner inte kan låsas från ett säkert initialt tillstånd för alltid.
Att anta att populära komponenter får tillräckligt med uppmärksamhet för att de inte kan injiceras med oavsiktligt beteende i en attack i leveranskedjan utan en nästan omedelbar detektering för att förhindra skada är naivt och riskabelt. Du vill väl inte leva på kanten?
Om du stannar vid det här laget, då riskacceptans är det enda du kan göra: Detta är en decision som behöver dokumenteras i din hotmodell/riskbedömning, inklusive motiveringen för att acceptera risken och dess potentiella konsekvenser. Öka medvetenheten genom att kommunicera den till ledningen och andra relevanta parter. Vissa oförutsedda kan planeras när en skadlig komponent installeras eller inkluderas i din programvara, men detta är svårt eftersom angripare har många vägar att följa. Detaljerna i en leveranskedjeattack baserad på användningen av en skadlig komponent kommer drastiskt att förändra offentliggörandet av händelsen, vilket förmodligen är obligatoriskt enligt din organisations regelverk. Du kan också ta itu med kompenserande kontroller or överföringsrisk t.ex. med försäkring.
Det finns dock kontroller som hanterar hotet och som bör övervägas om du inte är nöjd med risktagandet. Läs vidare.
Vad fungerar mot attacker med skadliga komponenter
Hantering av solid version
Versionslåsning med kontrollerade och välgrundade versionsbumpar är rätt väg att gå, för att balansera behovet av att ta bort sårbarheter utan att få skadlig kod. Men kom ihåg missuppfattning nr 3: Versionslåsning ensamt räcker inte för att blockera skadlig kod som kommer från nya versioner, eftersom du i framtiden kommer att behöva uppdatera versioner i alla direkta eller indirekta beroenden. I det ögonblicket behöver du tillräckligt starka bevis för att alla modifierade versioner inte innehåller skadlig kod.
Tidig varning
Ett sätt att hantera problemet med skadliga komponenter är ett tidigt varningssystem (här kallat Tidig varning om skadlig kod eller MEW), där nya versioner som publiceras (för nya eller befintliga komponenter) analyseras av en detekteringsmotor, som när tillräckligt med bevis hittas kan klassificera den nya versionen som potentiellt skadlig.
Automatisering är avgörande här, eftersom det är omöjligt att manuellt granska alla nya komponenter med nuvarande publiceringstakt. Så detekteringsmotorn behöver kombinera en mängd olika tekniker, kanske inklusive statisk, dynamisk och funktionsanalys, användarrykte och bevis som kommer från avvikelser mellan komponentens metadata och tarball-innehållet, eller mellan tarball och källförvaret där komponenten förmodas komma ifrån.
Det finns en mörk zon mellan publiceringstiden och när motorn analyserar komponentinnehållet, men det bör inte överstiga några minuter. Schemat kan ändras, till exempel genom att vänta på att nya komponenter analyseras innan de tillåts installeras och användas i programvarubygget. pipelines, eller analysera dem på begäran vid behov. En komponent i en given version är oföränderlig [3], så den behöver bara analyseras en gång.
Fullständig automatisering är inte möjlig, och en säkerhetsgranskning för potentiellt skadliga komponenter behövs. Se upp för förespråkare för digitala universalmedelAI och maskininlärning är inte tillräckligt utvecklade för att få sista ordet när det gäller att bekräfta om en misstänkt komponent innehåller skadlig kod. Visst, maskininlärning spelar en nyckelroll i detekteringsmotorn för att klassificera indatakomponenten från de råa bevis som samlats in, men när komponenten väl är "satt i karantän" är det sista ordet på den manuella granskningen av ett säkerhetsteam med erfarenhet av skadliga komponenter. Detta bekräftar eventuell potentiell skadlig kod eller omklassificerar den som säker. Och tidsperioden är inom timintervallet.
Registret rapporterar om den skadliga versionen/komponenten; registret utför sedan sin granskning för att bekräfta och fortsätter med offentliggörande och borttagning från registret. Vissa register har ett säkerhetspaket. Tidsintervallet här är dagarna eller veckorna sedan publiceringen, vilket är 'uppehållstid"eller"exponeringsfönster' för de flesta skadliga komponenter.
Är det möjligt att veta om en komponentversion är skadlig?
Så för tidig varning behöver vi ge ett tillfredsställande svar på denna fråga: Hur kan jag veta att ett bibliotek eller paket är (inte) skadligt? Hur samlar jag tillräckligt med bevis på skadligt beteende? Möjligt, men svårt, eftersom motståndarna använder mycket uppfinningsrikedom för att undvika upptäckt. Det finns olika tillvägagångssätt, alla med för- och nackdelar.
Statisk analys kan undersöka alla exekveringsvägar, kontrollera tekniker som används av angripare utan att köra komponenten, och utföra förbehandlingsuppgifter som avobfuskering eller dechiffrering. När angripare försöker dölja sina upptåg är obfuskeringsförsök verkligen bevis på skadlig kod (men observera att legitima komponenter döljer kod för att bevara immateriella rättigheter, vilket motsäger "öppen källkod”). Endast en minoritet av mycket sofistikerade attacker med stark obfuskation behöver sandlådebehandling, men sådan stark obfuskation är ett tydligt tecken på illvilja. Observera att konventionella SAST Verktyg utformades för oavsiktliga sårbarheter, inte för illvilliga avsikter som bakdörrar.
Dynamisk analys kör komponenten och undersöker svaret genom att instrumentera körtiden, vanligtvis genom att tillhandahålla en sandlådemiljö. Skadligt beteende som utlöses under vissa förhållanden kan passera oupptäckt: observera att skadlig kod kan använda undanflyktstekniker som Virtualisering/Sandbox Evasion att endast aktiveras när den inte granskas noga, och även ett tydligt tecken på skadlig aktivitet för alla statiska analysmotorer.
Kompetensanalys tar hänsyn till vad komponenten gör: vart den ansluter till, vilka filer den öppnar, vilka kommandon eller program som körs, vilken terminal- eller enhets-I/O som utförs eller vilka systemanrop som anropas. Denna fingeravtrycksanalys av beteende kan jämföras (för en befintlig komponent) mellan versioner, så när oväntat beteende upptäcks kan dessa bevis väcka misstanke om potentiell skadlig aktivitet som injicerats i den nya versionen. Denna metod följer de prioriteringssteg som säkerhetsanalytiker följer när de konfronteras med potentiell skadlig kod: en inspektion med hjälp av strängar eller liknande verktyg. Denna metod upptäcker skadligt beteende oavsett utlösande villkor och fungerar när ingen källkod finns tillgänglig.
Kontextanalys samlar in information om hur komponenten publicerades och av vem. Kampanjer från ondskefulla aktörer använder ofta ett/nya användarkonton som inte är föremål för någon strikt granskningsprocess. Att spåra tidigare aktivitet kan ge insikter om den underliggande användaren, främst för avvikelser som kan antyda en potentiell kompromiss. Rykte är så svårt att förtjäna och så lätt att förlora! En användare utan tidigare aktivitet är neutral, men karma jagar de ondskefulla. Hacktivister, eller vanliga användare vars publiceringsuppgifter är stulna, bör spåras noggrant.
En annan kontextuell information är eventuella avvikelser mellan källförvaret som ska ha använts för att skapa komponentens tarball och innehållet i själva tarballen. Och även att följa god praxis, som att skapa taggar eller utgåvor i källförvaret som matchar versionerna av komponenten som publiceras i det offentliga registret. När källförvaret vid ett visst commit är taggad med release, och sedan plötsligt en version inte följer den, är det ensamt starka bevis på att komponenten kan vara befläckad: den ondskefulla aktören kan ha komprometterat kontot som används för att publicera komponenten, men har inga skrivrättigheter i källkodsförrådet). Många attacker upptäcks rutinmässigt med hjälp av dessa regler: till exempel Ledger-attack skulle lätt kunna upptäckas på detta sätt. Kontextanalys identifierar därför sådana avvikelser i publiceringsprocessen.
Beroendebrandvägg
Ett annat tillvägagångssätt är att ha en omfattande vitlista över komponenter för alla beroendegrafer som används i din programvara, så i alla versioner pipeline körs i din organisation kan endast godkända komponentversioner installeras och användas.brandvägg” tillämpas med hjälp av ett internt register där tar-filer för de tillåtna komponentversionerna hanteras (cachade eller via proxy). Observera att vitlistor inte fungerar om du inte har tekniken för att klassificera nya versioner som rimligt säkra så att de kan läggas till i vitlistan.
Observera att tidig varning (snabb upptäckt så snart som möjligt efter publicering av den nya versionen) måste kombineras med något sätt att proaktivt använda informationen för att blockera komponenten som påverkar bygget. pipelineeller utvecklarnas maskiner [4]Vi kallar detta "beroende brandvägg”: en karantänmekanism för att skydda automatiserade byggen från skadliga paket. Interna paket och avbildningsregister är bra för att isolera organisationer från yttre ondska, men tillräckligt starka bevis är nödvändiga för att karantänen ska vara effektiv.
Runtime Sandboxing
Ett alternativt tillvägagångssätt för detektering vid publiceringstillfället är att analysera beteende vid körning. Tanken är att fånga upp det förväntade beteendet från programvaran och upptäcka (eller blockera) eventuella avvikelser som hittas. Denna åtgärd har problemet att behöva instrumentera körtiden för övervakning eller blockering, och det är en lovande idé som kommer att läggas till i arsenalen av skyddsmekanismer mot skadliga komponenter.
Att sätta en omfattande strategi
Den rekommenderade strategin behöver kombinera olika tekniker i programvaruutvecklingsprocessen och ta kontroll över versionsuppdateringar för att blockera inkommande skadliga komponenter. Vi måste möjliggöra versionslåsning för att undvika automatisk infektion med uppdateringar av versioner för att få korrigeringar för de sårbarheter som är viktiga; en snabb och effektiv bedömning av direkta och indirekta beroenden under versionsuppdateringar för att ha tillräckligt med bevis för att de inte är behäftade med skadlig kod. Programvaruversioner som är beroende av kända skadliga komponenter måste blockeras. Och allt detta måste tillämpas.
Använd versionsfästning när det är möjligt, eftersom det gör byggen mer reproducerbara. Versionsfästning med kontrollerade, manuellt godkända versionsbumparoch assisterad av hjälpteknik, bör bedöma om uppdateringen medför skadlig kod eller skadar programvaran, och förena uppdatering för att åtgärda sårbarheter med att undvika infektion med skadlig kod. Verktyg kan hjälpa till här genom att (1) prioritera vilka sårbarheter som verkligen är viktiga (nåbara och utnyttjas, med hög risk att bli måltavlor för angripare), (2) välja målversioner som är kompatibla med den nuvarande komponentanvändningen och inte skadar programvaran, (3) välja målversioner som inte innehåller skadligt beteende, och (4) göra versionsuppdateringen för direkta och indirekta beroenden snabb genom att föreslå ändringar i manifestfilerna som snabbt kan godkännas. Steg (3) behöver specifik information om skadliga komponenter så nära deras publiceringstid som möjligt.
Denna process för att uppdatera beroenden måste vara verkställas och verifierade på alla platser. Processen måste dokumenteras och alla inblandade parter bör utbildas, eftersom utveckling och programvarubyggande/distribution ofta externaliseras. Den CI/CD pipelines bör modifieras i enlighet därmed, så att automatisering inte tillåter ett skadligt indirekt beroende att slinka in i bygget: guardrails Att blockera bygget om det finns tillräckligt med bevis på potentiell skadlig kod i ett beroende är det rekommenderade tillvägagångssättet.
Om din organisation har ett internt register som fungerar som en säkerhetsproxy för att lagra de tillåtna komponentversionerna, måste du inhämta information om skadliga komponenter (förutom andra kriterier) för att granska en begärd komponent innan du lägger till den i listan över tillåtna versioner.
Att använda programvara med öppen källkod på ett säkert sätt är inte lätt, och skadlig kod måste beaktas fullt ut, med liknande ansträngningar vid hantering av sårbarheter.
En sista anmärkning: Källans ursprung, i form av programvaruattesteringar, genererade vid komponentens byggtid, är ytterligare en viktig del i arbetet med att spåra artefakten (komponentens tarball) med källkoderna och byggprocessen som producerade den. Observera att denna länk mellan källbilden + byggmiljön och den tillhörande programvaruartefakten (signerad av det betrodda byggsystemet) inte i sig hindrar att komponenten inte innehåller skadligt beteende, men gör det svårare för skurkarna att injicera skadlig kod. Och att göra proveniensvalidering till ett vanligt krav för att konsumera öppen källkodskomponenter kommer att ta lång tid, och bara nyligen tillagd till NPMAtt göra dessa betrodda bygg- och driftsättningssystem manipulationssäkra, eller att möjliggöra detektering av manipulering i bygget, är en annan historia som ligger utanför ramen för det här inlägget.
Ytterligare läsning
Nästa avsnitt Skadliga paket med öppen källkod: Xygeni-metoden kommer att presentera den strategi vi följer på Xygeni för vår Tidig varning om skadlig kod (MEW)-system. Nya paketversioner i de publika paket- och bildregistren skannas och bevis erhålls med hjälp av en kombination av statisk, dynamisk, funktions- och kontextuell analys. Bevisen, i kombination med användarrykte och historik över ändringar i källkodsdatabaser, möjliggör en helt automatiserad klassificering av en komponent i högrisk- och troligen skadliga kategorier. Systemet lär sig av tidigare bevis som samlats in från paket för att minska falska positiva resultat till ett minimum.
Prenumererade organisationer får en varningsnotis för komponenter de använder, direkt eller indirekt, när en skadlig version kategoriseras. Sedan gör våra analytiker en manuell analys, som bekräftar eller avvisar klassificeringen. För bekräftad skadlig kod meddelas det offentliga registret så att det kan utföra sin egen analys och vanligtvis ta bort den skadliga versionen eller vidta ytterligare åtgärder, såsom att blockera eller ta bort användarkontot i fråga.
Vi kommer att förklara hur vi hjälper NPM, PyPI, GitHub och andra viktiga infrastrukturer i öppen källkods-ekosystemet att minska den tid som en ny skadlig komponent som publiceras förblir aktiv tills den bekräftas som skadlig kod och tas bort från registret. Och hur organisationer kan dra nytta av MEW-systemet för att få ett mycket bättre skydd mot attacker i programvaruleveranskedjan som involverar öppen källkodskomponenter.
- [1] Hur som helst måste användare av komponenten kontrollera om komponentens tarball är cachad eller registrerad någonstans, till exempel i ett internt register, så att sjukdomen utrotas.
- [2] Den paketerade komponenten innehåller ett manifest som deklarerar dess innehåll och metadata, källkod eller kompilerad kod, installationsskript och ytterligare objekt som testsviter, enligt ett paketeringsformat och vanligtvis i komprimerad form. Detta kallas "komponent-tarball".
- [3] Även om den skadliga aktören kan modifiera en publicerad komponent på grund av ett intrång i själva registret, kan en vanlig kryptografisk sammanfattning upptäcka alla förändringar i tar-filen efter att analysen är klar.
- [4] Kom ihåg att vissa skadliga komponenter körs vid installationstillfället, så det kan påverka utvecklarnoder som omedvetet kör "npm install X" med X som en skadlig komponent.




