Dela via


Metodtips för en säker leverantörskedja för programvara

Öppen källkod finns överallt. Det finns i många proprietära kodbaser och communityprojekt. För organisationer och individer är frågan i dag inte om du använder öppen källkod eller inte, utan vilken öppen källkod du använder och hur mycket.

Om du inte känner till vad som finns i din leverantörskedja för programvara kan en överordnad säkerhetsrisk i ett av dina beroenden vara dödlig, vilket gör dig och dina kunder sårbara för en potentiell kompromiss. I det här dokumentet går vi närmare in på vad termen "leverantörskedja för programvara" betyder, varför det är viktigt och hur du kan hjälpa till att skydda projektets leveranskedja med bästa praxis.

Tillståndet för Octoverse 2020 – öppen källkod

Beroenden

Termen leverantörskedja för programvara används för att referera till allt som går in i din programvara och var den kommer ifrån. Det är beroenden och egenskaper för dina beroenden som din programvaruförsörjningskedja är beroende av. Ett beroende är vad din programvara behöver köra. Det kan vara kod, binärfiler eller andra komponenter och var de kommer ifrån, till exempel en lagringsplats eller pakethanterare.

Den innehåller vem som skrev koden, när den bidrogs, hur den granskades för säkerhetsproblem, kända sårbarheter, versioner som stöds, licensinformation och nästan allt som berör den när som helst i processen.

Leveranskedjan omfattar även andra delar av din stack utöver ett enda program, till exempel bygg- och paketeringsskript eller den programvara som kör infrastrukturen som programmet förlitar sig på.

Sårbarheter

Idag är programvaruberoenden genomgripande. Det är vanligt att dina projekt använder hundratals beroenden med öppen källkod för funktioner som du inte behövde skriva själv. Det kan innebära att de flesta av programmet består av kod som du inte har skapat.

Tillståndet för Octoverse 2020 – beroenden

Möjliga sårbarheter i dina beroenden från tredje part eller med öppen källkod är förmodligen beroenden som du inte kan kontrollera lika hårt som koden du skriver, vilket kan skapa potentiella säkerhetsrisker i leveranskedjan.

Om ett av dessa beroenden har en säkerhetsrisk är chansen stor att du också har en sårbarhet. Detta kan vara skrämmande eftersom ett av dina beroenden kan ändras utan att du ens vet. Även om det finns en säkerhetsrisk i ett beroende i dag, men inte är exploaterbar, kan den utnyttjas i framtiden.

Att kunna dra nytta av tusentals utvecklare och biblioteksförfattare med öppen källkod innebär att tusentals främlingar effektivt kan bidra direkt till din produktionskod. Din produkt, genom din försörjningskedja för programvara, påverkas av opatchade sårbarheter, oskyldiga misstag och till och med skadliga attacker mot beroendekedjan.

Kompromisser i leveranskedjan

Den traditionella definitionen av en leveranskedja kommer från tillverkning; det är den kedja av processer som krävs för att göra och leverera något. Det omfattar planering, leverans av material, tillverkning och detaljhandel. En leverantörskedja för programvara är liknande, förutom i stället för material, det är kod. I stället för tillverkning är det utveckling. I stället för att gräva malm från marken kommer kod från leverantörer, kommersiell eller öppen källkod, och i allmänhet kommer koden med öppen källkod från lagringsplatser. Att lägga till kod från en lagringsplats innebär att produkten är beroende av koden.

Ett exempel på en attack i leverantörskedjan för programvara inträffar när skadlig kod avsiktligt läggs till i ett beroende, med hjälp av försörjningskedjan för det beroendet för att distribuera koden till dess offer. Leveranskedjeattacker är verkliga. Det finns många metoder för att attackera en leveranskedja, från att direkt infoga skadlig kod som en ny deltagare, till att ta över en deltagares konto utan att andra märker det, eller till och med kompromettera en signeringsnyckel för att distribuera programvara som inte är officiellt en del av beroendet.

En attack i leverantörskedjan för programvara är i sig själv sällan slutmålet, snarare är det början på en möjlighet för en angripare att infoga skadlig kod eller tillhandahålla en bakdörr för framtida åtkomst.

Tillståndet för Octoverse 2020 – Livscykel för sårbarhet

Oskickad programvara

Användningen av öppen källkod idag är betydande och förväntas inte sakta ner när som helst snart. Med tanke på att vi inte kommer att sluta använda programvara med öppen källkod är hotet mot leveranskedjans säkerhet oskickad programvara. Hur kan du hantera risken för att ett beroende av projektet har en säkerhetsrisk?

  • Veta vad som finns i din miljö. Detta kräver att du identifierar dina beroenden och eventuella transitiva beroenden för att förstå riskerna med dessa beroenden, till exempel sårbarheter eller licensbegränsningar.
  • Hantera dina beroenden. När en ny säkerhetsrisk identifieras måste du avgöra om du påverkas och i så fall uppdatera till den senaste versionen och säkerhetskorrigeringen som är tillgänglig. Detta är särskilt viktigt för att granska ändringar som introducerar nya beroenden eller regelbundet granskar äldre beroenden.
  • Övervaka din leveranskedja. Det här är genom att granska de kontroller som du har för att hantera dina beroenden. Detta hjälper dig att framtvinga mer restriktiva villkor som ska uppfyllas för dina beroenden.

Tillståndet för Octoverse 2020 – Rekommendationer

Vi kommer att ta upp olika verktyg och tekniker som NuGet och GitHub tillhandahåller, som du kan använda idag för att hantera potentiella risker i projektet.

Veta vad som finns i din miljö

Paket med kända sårbarheter

📦 Paketkonsument | 📦🖊 Paketförfattare

.NET 8 och Visual Studio 17.8 har lagt till NuGetAudit, som varnar för direkta paket med kända säkerhetsrisker under återställningen. .NET 9 och Visual Studio 17.12 ändrade standardvärdet för att varna även för transitiva paket.

NuGetAudit kräver att en källa tillhandahåller en känd sårbarhetsdatabas, så om du inte använder nuget.org som paketkälla bör du lägga till den som en granskningskälla.

När NuGet varnar dig är sårbarheten allmänt känd. Angripare kan använda det här offentliga avslöjandet för att utveckla attacker för mål som inte har korrigerat sina program. När du får en varning om att ett paket som ditt projekt använder har en känd säkerhetsrisk bör du därför snabbt vidta åtgärder.

NuGet-beroendediagram

📦 Paketkonsument

Du kan visa dina NuGet-beroenden i projektet genom att titta direkt på respektive projektfil.

Detta finns vanligtvis på någon av två platser:

Beroende på vilken metod du använder för att hantera dina NuGet-beroenden kan du också använda Visual Studio för att visa dina beroenden direkt i Solution Explorer eller NuGet Package Manager.

För CLI-miljöer kan du använda dotnet list package kommandot för att lista ut projektets eller lösningens beroenden. Du kan också använda dotnet nuget why kommandot för att förstå varför transitiva paket (de som inte refereras direkt av projektet) tas med i projektets paketdiagram.

Mer information om hur du hanterar NuGet-beroenden finns i följande dokumentation.

GitHub-beroendediagram

📦 Paketkonsument | 📦🖊 Paketförfattare

Du kan använda GitHubs beroendediagram för att se de paket som ditt projekt är beroende av och de lagringsplatser som är beroende av det. Detta kan hjälpa dig att se eventuella sårbarheter som identifierats i dess beroenden.

Mer information om Beroenden för GitHub-lagringsplatser finns i följande dokumentation.

Versionsberoenden

📦 Paketkonsument | 📦🖊 Paketförfattare

För att säkerställa en säker leveranskedja med beroenden vill du se till att alla dina beroenden och verktyg uppdateras regelbundet till den senaste stabila versionen eftersom de ofta innehåller de senaste funktionerna och säkerhetskorrigeringarna för kända sårbarheter. Dina beroenden kan innehålla kod som du är beroende av, binärfiler som du använder, verktyg som du använder och andra komponenter. Detta kan omfatta:

Hantera dina beroenden

NuGet föråldrade och sårbara beroenden

📦 Paketkonsument | 📦🖊 Paketförfattare

Du kan använda dotnet CLI för att lista eventuella kända inaktuella eller sårbara beroenden som du kan ha i projektet eller lösningen. Du kan använda kommandot dotnet list package --deprecated eller dotnet list package --vulnerable för att ge dig en lista över kända utfasningar eller sårbarheter. NuGetAudit kan varna dig om kända sårbara beroenden och aktiveras som standard när en källa tillhandahåller en sårbarhetsdatabas.

GitHub-sårbara beroenden

📦 Paketkonsument | 📦🖊 Paketförfattare

Om projektet finns på GitHub kan du använda GitHub Security för att hitta säkerhetsrisker och fel i projektet. Dependabot åtgärdar dem genom att öppna en pull-begäran mot din kodbas.

Att fånga sårbara beroenden innan de introduceras är ett mål för rörelsen "Skift vänster" . Att kunna ha information om dina beroenden, till exempel deras licens, transitiva beroenden och beroendens ålder hjälper dig att göra just det.

Mer information om Dependabot-aviseringar och säkerhetsuppdateringar finns i följande dokumentation.

NuGet-konfiguration

📦 Paketkonsument

Lägg till en nuget.config fil i roten på projektlagringsplatsen. Detta anses vara en bästa praxis eftersom det främjar repeterbarhet och säkerställer att olika användare har samma NuGet-konfiguration. Vi rekommenderar att du lägger till clear element för att säkerställa att ingen användar- eller datorspecifik konfiguration tillämpas. Läs mer om hur inställningar tillämpas.

Till exempel:

<configuration>
  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
  <packageSourceMapping>
    <clear />
  </packageSourceMapping>
</configuration>

NuGet-flöden

📦 Paketkonsument

Använd paketkällor som du litar på. När du använder flera offentliga och privata NuGet-källflöden kan ett paket laddas ned från någon av feeds. För att säkerställa att ditt bygge är förutsägbart och skyddat från kända attacker, till exempel Beroendeförvirring, är det en bra praxis att veta vilka specifika flöden dina paket kommer från. Du kan använda en enda feed eller privat feed med överordnade funktioner för skydd.

Mer information om hur du skyddar dina paketfeeds finns i 3 sätt att minska risken när du använder privata paketfeeds.

När du använder ett privat flöde läser du metodtipsen för säkerhet för att hantera autentiseringsuppgifter.

Principer för klientförtroende

📦 Paketkonsument

Det finns policyer som du kan välja som kräver att de paket du använder är signerade. På så sätt kan du lita på en paketförfattare, så länge den är författare signerad, eller lita på ett paket om det ägs av en specifik användare eller ett konto som är en lagringsplats signerad av NuGet.org.

Information om hur du konfigurerar principer för klientförtroende finns i följande dokumentation.

Lås filer

📦 Paketkonsument

Lås filer lagrar hashen för paketets innehåll. Om innehållshash för ett paket som du vill installera matchar med låsfilen, säkerställer det att paketet upprepar sig.

Information om hur du aktiverar låsfiler finns i följande dokumentation.

Mappning av paketkälla

📦 Paketkonsument

Med paketkällans mappning kan du centralt deklarera vilken källa varje paket i lösningen ska återställas från i din nuget.config-fil.

Information om hur du aktiverar paketkällans mappning finns i följande dokumentation.

Säkra datorer

Katalogbehörigheter

📦 Paketkonsument

I Windows och Mac och vissa Linux-distributioner är användarkontots hemkataloger privata som standard. Vissa Linux-distributioner gör dock användarkataloger läsbara av andra konton på samma dator som standard. Dessutom finns det flera konfigurationsalternativ för att omdirigera NuGets globala paketmapp och HTTP-cache till platser som inte är standard. Lösningar, projekt och lagringsplatser kan också skapas utanför användarens hemkatalog.

Om du använder paket som inte finns på nuget.org kan dessa paket avslöjas för personer som inte ska ha åtkomst till dessa paket om något annat konto på datorn kan läsa NuGets globala paket eller HTTP-cachekataloger eller projektets build output-katalog.

I Linux dotnet nuget update source ändrar nuget.config filbehörigheter så att den endast kan läsas av filägaren. Men om du redigerar nuget.config-filen på något annat sätt och filen finns på en plats där andra konton kan läsa filen, kan det finnas information om paketkällans URL eller paketkällans autentiseringsuppgifter. Du bör se till att alla nuget.config filer inte kan läsas av andra användare på samma dator.

Lösningar i katalogen för nedladdningar

📦 Paketkonsument

Du bör vara extra försiktig om du arbetar med lösningar eller projekt i din nedladdningskatalog. NuGet ackumulerar inställningar från flera konfigurationsfiler, och MSBuild importerar vanligtvis Directory.Build.props, Directory.NuGet.props, Directory.Build.targets och potentiellt andra filer, från valfri överordnad katalog, ända fram till filsystemroten.

Mappen för nedladdningar har ytterligare risk, eftersom det vanligtvis är standardplatsen där webbläsare laddar ned filer från Internet

Skapa agenter

📦 Paketkonsument

Byggagenter (CI-agenter) som inte återställs till ett initialt tillstånd efter varje bygge har flera risker som måste beaktas.

Mer information om säkra sätt att hantera autentiseringsuppgifter finns i dokumentationen om hur du använder paket från autentiserade feeds.

Mer information om hur du ändrar de kataloger som NuGet lagrar data i finns i dokumenten om att hantera globala paket, cacheminnen och temporära mappar. Dessa kataloger bör konfigureras till en katalog som CI-agenten rensar efter varje version.

Observera att alla paket som används av projektet kan finnas kvar i projektets utdatakatalog för bygget. Om ditt projekt använder paket från autentiserade källor kan andra användare av samma CI-agent få obehörig åtkomst till paketsammansättningarna. Därför bör du också rensa ditt repo i slutet av bygget, även när bygget misslyckas eller avbryts.

Övervaka din leveranskedja

GitHub-hemlig genomsökning

📦🖊 Paketförfattare

GitHub söker igenom lagringsplatser efter NuGet API-nycklar för att förhindra bedräglig användning av hemligheter som har begåtts av misstag.

Mer information om hemlig genomsökning finns i Om hemlig genomsökning.

Signering av författarpaket

📦🖊 Paketförfattare

Författaresignering låter en paketförfattare stämpla sin identitet på ett paket och låta en konsument verifiera att det kom från dig. Detta skyddar dig mot innehållsmanipulering och fungerar som en enda sanningskälla om paketets ursprung och paketets äkthet. När det kombineras med principer för klientförtroende kan du kontrollera att ett paket kom från en specifik författare.

Information om hur du skriver under ett paket finns i Signera ett paket.

Reproducerbara byggen

📦🖊 Paketförfattare

Reproducerbara versioner skapar binärfiler som är byte-för-byte identiska varje gång du skapar den och innehåller källkodslänkar och kompilatormetadata som gör att paketkonsumenten kan återskapa binärfilen direkt och verifiera att byggmiljön inte har komprometterats.

Mer information om reproducerbara versioner finns i Skapa paket med Källlänk och specifikationen för reproducerbar byggverifiering .

Two-Factor-autentisering (2FA)

📦🖊 Paketförfattare

Varje konto på nuget.org har 2FA aktiverat. Detta lägger till ett extra säkerhetslager när du loggar in på ditt GitHub-konto eller ditt NuGet.org-konto.

Paket-ID-prefiksreservation

📦🖊 Paketförfattare

För att skydda identiteten för dina paket kan du reservera ett paket-ID-prefix med respektive namnområde för att associera en matchande ägare om paket-ID-prefixet faller under de angivna kriterierna.

Mer information om hur du reserverar ID-prefix finns i Paket-ID-prefixreservation.

Avveckla och dölja ett sårbart paket

📦🖊 Paketförfattare

Om du vill skydda .NET-paketekosystemet när du är medveten om en sårbarhet i ett paket som du har skapat, gör du ditt bästa för att avskriva och avlista paketet så att det inte syns för användare som söker efter paket. Om du använder ett paket som är inaktuellt och olistat bör du undvika att använda paketet.

För att lära dig hur man avskriver och tar bort från listan ett paket, se följande dokumentation om att avskriva och att ta bort paket från listan.

Överväg också att rapportera det kända till GitHub Advisories-databasen.

Sammanfattning

Din leverantörskedja för programvara är allt som går in i eller påverkar din kod. Även om kompromisser i leveranskedjan är verkliga och växer i popularitet, är de fortfarande sällsynta; Så det viktigaste du kan göra är att skydda din leveranskedja genom att vara medveten om dina beroenden, hantera dina beroenden och övervaka din leveranskedja.

Du har lärt dig om olika metoder som NuGet och GitHub tillhandahåller som är tillgängliga för dig idag för att vara mer effektiva när det gäller att visa, hantera och övervaka din leveranskedja.

Mer information om hur du skyddar världens programvara finns i State of the Octoverse 2020 Security Report(Tillstånd för octoverse 2020-säkerhetsrapporten).