Kontinuerlig integration och kontinuerlig leverans (CI/CD) pipelineär grunden för alla mjukvaruorganisationer som bygger mjukvara på ett "modernt" sätt. Automatisering ger stor kraft, men de flesta utvecklare missar det ansvar det innebär.
DeveloperJa, vi tar CI/CD säkerhet på allvar och ha stark kontroll över kodansvariga, granska commits före sammanslagningar; jobb och pipelines underhålls av högre personal, de ser till att inte läcka hemligheter i pipelines. Och verktyget installerades av personal som är bekant med saken. Vad kan gå fel?
Bäste utvecklare, CI/CD system är komplexa. Dess breda attackyta lockade illvilliga aktörer. Var försiktig och aldrig övermodig.
Standardkonfigurationen behålls ibland och blir hackares bästa vän. Kritiska brister kan förekomma i CI/CD pipeline källor, i systemets konfiguration, eller kring processen och sammanhanget för pipeline och hur den utlöses.
I det här inlägget ska vi sätta oss in i de dåliga skådespelarnas skor. Tänk dig att vi läser funderingarna från M3M3N70 (Memento Mori?) och Träskraseri någonstans i den mörka webben, förmodligen på ett icke-västerländskt språk, men missa aldrig att ondskan sprids över hela världen.
På den gamla goda tiden var det så enkelt…
M3M3N70Tillbaka till den gamla goda tiden var vår verksamhet sååå enkel… Nolldagarsstrategier var lättillgängliga, appar var vidöppna med lättutnyttjade sårbarheter, och vi kunde röra oss i sidled på ett ögonblick.
Träskraseri: Fu#@Helvete! Några galna där ute än, men saker och ting har förändrats. De stora aktörerna lade massor av vikt vid det där AppSec-skiten.
M3M3N70Japp. Men de nya dårarna är utvecklarna. För oss har det varit lättare att välja de verktyg som de här använder. CI:n, i synnerhet, är en guldgruva! Molnåtkomsttokens, SCM inloggningsuppgifter, lösenord för produktionsdatabaser, privata SSH-nycklar, andra CI-användares inloggningsuppgifter… Att hoppa från de tråkiga utvecklingsgrejerna till det riktiga var ganska trivialt.
Automatisering för att bygga, testa och driftsätta programvara med en CI/CD Verktyget behöver ofta skicka hemligheter till kommandon i steg. Och ofta läcks de ut, med ökända konsekvenser.
Pipelinebehöver hemligheter som ibland läcker ut
M3M3N70: The code monkeys slipped their AWS keys in a pipeline on a GitHub commit, later they removed the thing but not changed git history. For our scripts it was trivial to scan the history, grab the key and wreak havoc.
Kanske var det på den gamla goda tiden att hitta i Gits historia en .env filen (utvecklaren glömde att lägga till den i .gitignore):
AWS_ACCESS_KEY_ID=AKIA...AWS_SECRET_ACCESS_KEY=wJalrXUtn...AWS_REGION=us-east-1APP_FOLDER=...S3BUCKET=...
som användes i ett GitHub-arbetsflöde .github/deploy.yaml som innehöll något i stil med detta:
jobs:
build:
name: Automated build and deployment into AWS
runs-on: ubuntu-22.04
steps:
# Load environment from .env file
- id: dotenv
uses: falti/dotenv-action@v1.0.2
- name: Configure AWS Credentials
uses:
with:
args: --acl public-read --follow-symlinks --delete
aws-access-key-id: $
aws-secret-access-key: $
aws-region: $
# ... build steps skipped ...
- name: Upload compiled code for deployment
working-directory: $/packaged_app
run: aws s3 cp my-app.zip s3://$
- name: Deploy the app
run: aws deploy create-deployment ...
M3M3N70: wow! De där aws-nycklarna fungerade! Vi testade först en oskadlig ändring i appen, sedan lade vi till "sting" eftersom de där killarna verkade omedvetna. Bingo! Vilken kampanj…
Den onde aktören använde helt enkelt AWS-nycklarna för att ladda upp en modifierad applikation med skadlig kod och körde sedan deploy-kommandot med dessa inloggningsuppgifter. De läckta hemligheterna, tillsammans med informationen i pipeline”Vilken kampanj!” betyder förmodligen att Memento orsakade förödelse hos det stackars offret.
Vad Memento berättar här är att när en hemlig läcka inträffar, som AWS-åtkomstnycklar i exemplet, måste du återkalla hemligheten (rotera ovanstående nycklar). blir omedelbartDet finns alltid en exponeringsfönster mellan det läckande commit och den hemliga ogiltigförklaringen; Att skriva om Git-historiken är svårt (även den tuffaste auktoritära staten försökte sig på sådan historieskrivning, utan framgång) och förmodligen ineffektivt (våra vänner kanske klonade före förvaret med den hemliga läckan commit). Rotera tangenterna omedelbart och be medan du läser aktivitetsloggar för det riktade kontot under exponeringsfönstret!
Förmodligen borde organisationer förbjuda användning av långsiktiga hemligheter i CI/CD pipelinesoch ersätt dem med temporala autentiseringsuppgifter. I föregående exempel med AWS-nycklar i GitHub-åtgärder är det säkrare att använda en OpenID Connect (OIDC)-leverantör för att få kortlivade inloggningsuppgifter som behövs för åtgärder.
TräskraseriDu hade sån tur! Att läcka skript med hårdkodade nycklar var vanligt förr i tiden, även på offentligt tillgängliga S3-buckets. Allt du behövde göra var att bläddra bland objekten i bucketen och göra lite grepning för att hitta intressanta saker.
Ibland var området som användes för distribution (en AWS S3-bucket i det här exemplet) öppet för läsning från utomstående, på grund av en konfigurationsfel (som inte upptäcktes). Vad Träskraseri användes var något i stil med detta:
aws s3 ls --recursive s3://<bucket_name>/<path>/ | \
awk '{print $4}' | \
xargs -I FNAME sh -c "echo FNAME; \
aws s3 cp s3://<bucket_name>/FNAME - | \
grep '<regex_pattern>'"
Bucketen skapades troligen i en provisioneringsmall som kunde skannas automatiskt efter säkerhetsbrister.
Verktygets standardkonfiguration var en leksak för oss
För att ge konkreta exempel, låt oss prata om Jenkins, ett av de mest populära CI-verktygen.
TräskraseriKommer du ihåg kryssrutan "Aktivera säkerhet" i Jenkins, och hur många organisationer som valde att inte aktivera den för enkelhets skull? Och de där "Vem som helst kan göra vad som helst”behörighetskombinationer som standard? Och de där irriterande Jenkins-pluginen, som GitHub OAuth-pluginKillen som konfigurerade det valde både "Ge läsbehörigheter till alla autentiserade användare" och "Använd GitHub-arkivbehörigheter", vilket gav oss tillgång till alla deras projekt.
(Ursäkta, Jenkins, för att jag satte dig som exempel 😉
Håll dig skicklig (till och med beroende) av säkerhetsprinciper. En är Säker som standard Princip: Kontrollerna bör som standard ha de säkraste inställningarna. Säkerhet bör byggas in i CI/CD verktyg och pipelinefrån grunden, snarare än att vara en eftertanke. Men användarvänlighet och bekvämlighet kolliderar ofta med säkerhet.
För Jenkins fall är den inbyggda autentiseringen för ömtålig: använd aldrig de inbyggda autentiseringsmekanismerna i JenkinsVälj hellre en tredjepartsmekanism (SAML, LDAP, Google ...), med pluginet Role-based Authorization Strategy ("RBAC"). Och var extremt försiktig med admin konto.
Ta hand om hur jobb och pipeline filer i Jenkins hanteras. Samma sak gäller Konfiguration-som-kod-plugin och dess konfigurationsfiler, som gäller för Jenkins-konfigurationen.
Flytta från egenhosting CI/CD system till molnbaserade SaaS-system eliminerar vissa potentiella risker som möjliggör lateral förflyttning inom organisationsnätverket, men lägger till andra, som att behöva öppna externa kopplingar mellan befintliga interna system och de externaliserade. CI/CD verktyg.
Organisationer bör utövacisnoggrannhet vid härdning av CI/CD systemet, med början med de mest restriktiva inställningarna och gradvis upp med de minimalt nödvändiga behörigheterna för pipeline steg.
Konfigurera säkerhet i CI/CD Verktyg kan vara komplicerade. Många har plugins eller tillägg som har de flesta sårbarheterna och behöver uppdateras.
Skannrar för säkerhetsfelkonfiguration för sådana komplexa verktyg, eller benchmarks, kan hjälpa.
Injicera kod pipeline kommandon för skojs skull och vinst
M3M3N70Har du någonsin använt utcheckningar av kod som inte är betrodd, vilka sårbara åtgärder och skript som är sårbara för kommandoinjektion?
Det här avsnittet visar att pipeline självt skulle kunna ha kodningsfel som gör det möjligt för dåliga aktörer att injicera godtycklig kodkörning i pipeline utan att ändra pipeline källan självTill exempel med hjälp av en PR
Ett första exempel på en olyckligt GitHub-arbetsflöde:
# INSECURE. Provided as an example only.
on:
pull_request_target #1
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: $ #2
- uses: actions/setup-node@v1
- run: |
npm install #3
npm build
# ... more steps ...
Kombinera pull_request_target En arbetsflödesutlösare med en explicit utcheckning av en otillförlitlig PR är en farlig metod som kan leda till att databaskomprometterats. I exemplet är den olyckliga kombinationen av:
pull_request_targethändelse, som som standard har skrivbehörighet till målförrådet och målförrådets hemligheter, även från externa forkar, och körs i kontexten av målförrådet för PR,- kolla in PR-koden från källan, otillförlitligt repo,
- utlösa alla skript som kan komma att fungera på PR-kontrollerat innehåll, som i fallet med
npm installoch - inte använda ett villkor för utlösningen
pull_request_targethändelsen ska endast köras om någon typ av etikett "denna PR har granskats" har tilldelats PR:n (externa användare kan inte tilldela etiketter till PR:n).
Ett andra exempel tar otillförlitliga input (från ett ärende, en kommentar eller pull request) som källa för argument som skickas till en pipeline kommando via uttryck. Detta är pipeline version av sårbarheten för kommandoinjektion i operativsystemet.
- name: Check title
run: |
title="$"
if [[ ! $title =~ ^.*:\ .*$ ]]; then
echo "Bad issue title"
exit 1
fi
Körningsoperationen genererar ett tillfälligt skalskript baserat på mallen, med $ ersatt, vilket gör den sårbar för injektion av shell-kommandon. En angripare med ett falskt GitHub-konto kan skapa ett problem med en titel a"; bad_code_goes_here;#, och pang!
TräskraseriÅh, de där killarna öppnade dörren för kommandoinjektion genom att helt enkelt öppna ett ärende…
Det fanns sårbarheter i kodkörning i GitHub-åtgärder, som gajira-kommentar, nu åtgärdat. Läs gärna "Otillförlitlig inmatning i GitHub-arbetsflöden" för fullständig information.
Sensmoralen i historien: Kassa aldrig ut och bygg aldrig PR från opålitliga källor utan att först granska PR:n. ”Otillförlitlig” här, såvida inte under drakonisk proveniensautentisering, kan betyda alla potentiellt kapade utvecklarkonton.
Oavsiktlig distribution av skadlig kod här!
Kontinuerlig distribution är automatiseringens klimax, men den klimaxen skulle kunna motverkas av bristen på lämpliga godkännandekontroller på pipeline strömma.
Riskerna med helautomatiserad distribution från källan commit till produktionssystem inkluderar risken för att skadlig kod distribueras till produktionsmiljöer utan att upptäckas, samt risken för att fel i distributionsprocessen orsakar störningar eller avbrott.
För att minska dessa risker rekommenderas det ofta att organisationer implementerar en "hård paus" i sin implementeringsprocess, vilket kräver mänskligt godkännande innan utgåvor distribueras till slutmiljöer.
De stänger dörrarna
TräskraseriDe där glädjefyllda standardlösenorden i CI/CD verktyg torkas bort. Åtkomst till
/var/lib/jenkins/secrets/initialAdminPasswordär nu ett död spår. Många verktyg tillhandahåller nu 2FA, som Covid gjorde populärt, och till och med den lataste kodapan som finns använder det!M3M3N70Vi kämpar mot 2FA, men det är inte så lätt. Det är svårt att nätfiska de där killarna, eftersom "Scatter Swine" gjorde med TwilioMed WebAuthn-nycklar är det mycket svårare. Vi kan åtminstone försöka stjäla cookies för att kringgå MFA, men behöver bryta sig in i utvecklarens låda.
Multifaktorautentisering är ett bra steg i rätt riktning för att begränsa risken för läckage av autentiseringshemligheter. De flesta moderna DevOps-verktyg stöder MFA. Och autentiseringsnycklar under WebAuthn / U2F (se FIDO2-projektet) är kanske det bästa alternativet för MFA i DevOps, om de hanteras korrekt.
TräskraseriDevOps-killarna vaknar upp. De har den förbannade grejen med "minst privilegier" i blodet. Och de är inte kod-apor längre. Nu blir vi tagna på bar gärning av granskare.
I själva verket, pipelineär nu lite mer robusta än för ett par år sedan, med svaga åtgärder och skript borttagna, och med ytterligare säkerhetsteststeg som till och med upptäckte våra droppers gömda i smyg. commitoch paket som vi kapade.
Fråga till läsaren: är processen att bygga programvaran från källor och driftsätta den i produktion en riskabel verksamhet? Kan du se din DevOps i skedet av gamla goda tider för de onda?
Slutliga rekommendationer
Var man ska börja med CI/CD pipelines?
Den första rekommendationen är enkel här: Var försiktig översyn pipelines (de är kritisk resurser) för säkerhetsproblem. Granskningar är kostsamma men nödvändiga och bör utföras korrekt. Granskare bör vara medvetna om vad de ska titta på. Varje steg måste kontrolleras för brister.
Kanske skulle en kombination av expertgranskare beväpnade med automatiserade skanningsverktyg för skadlig kod kunna hjälpa.
Den andra rekommendationen är att utbilda utvecklare som skriver pipelineoch underhålla dem på säkerhetSaker att tänka på:
- Hur man hanterar autentisering på rätt sätt med interna tjänster och molntjänster, och undviker besväret med att hantera långsiktiga inloggningsuppgifter.
- Hur man begränsar pipelines till exakt den uppsättning resurser den behöver tillgång till. Principen om minsta möjliga privilegier lyser upp igen.
- Hur man skriver stegen för att göra pipelines reproducerbar som versionsfästning och undviker sårbarheter vid kommandoinjektion.
- Hur man godkänner distributioner ur säkerhetsperspektivet (de är andra!): vilken säkerhet standards ska matchas och hur man lägger till motsvarande kontroller/grindar i pipelines.
En tredje rekommendation är att konfigurera CI/CD systemet med vederbörlig omsorgStark autentisering, inga standardlösenord eller osäkra inställningar, minimala behörigheter… Ta hand om sårbarheter i installerade plugins och tillägg. Detta kan vara fokus för följande inlägg, håll utkik.
Den fjärde rekommendationen är att utnyttja CI/CD pipelines för säkerhetsautomationAnalys av källkod (SAST), analys av källkomposition (SCA), kan skanning av hemlighetsläckor, verktyg för att förhindra skadlig kod, säkerhetsskannrar för containern eller automatiserade runtime-detektorer (DAST och skadlig kod) köras rutinmässigt på pipelineOch din organisation kan upprätthålla standardom täckning av säkerhetsskanning i CI/CD.
Kom ihåg att dessa verktyg ännu inte tar bort expertgranskning från ekvationen, annars kan du få en falsk känsla av trygghet.
Om du är skicklig på OWASP topp-tio, är ett bra nytt projekt OWASP Topp 10 CI/CD Säkerhetsrisk.
Anmärkning om ansvarsfriskrivning
(1) Exemplen i det här inlägget använder GitHub som SCM, AWS som molnleverantör och GitHub Actions eller Jenkins som CI/CD verktyg. De är inte svagare/säkrare än sina alternativ. Inga dåliga avsikter för publicitet! Dessa verktyg är kraftfulla och måste användas på rätt sätt.
Lagring M3M3N70 och Träskraseri är fiktiva karaktärer. Varje likhet med personer eller grupper, levande eller döda, är bara en slump… eller är det?
För att läsa mer
- Haymore, A. m.fl. 10 verkliga berättelser om hur vi har kompromissat CI/CD pipelines ”NCC-gruppen, januari 2022.
configure-aws-credentialsGitHub-åtgärd och Konfigurera OpenID Connect i Amazon Web Services för information om hur du kör AWS-kommandon för distribution i GitHub-arbetsflöden.- Lobacevski J. "Säkra dina GitHub-åtgärder och arbetsflöden Del 1: Förhindra pwn-förfrågningar"GitLab säkerhetslabb, december 2020.
- Lobacevski J. "Säkra dina GitHub-åtgärder och arbetsflöden Del 2: Otillförlitlig inmatning"GitLabs säkerhetslabb, januari 2021.
- OWASP. "OWASP Topp 10" CI/CD SäkerhetsriskerJuli 2022.
- Saltzer J. och Schroeder M. "Skydd av information i datorsystem"April 1975. Säkerhetsprinciperna utvecklades med tekniken, men 47 år senare är de flesta S&S-idéerna fortfarande i kraft.
- Storbritanniens NCSC. "Säkra byggandet och driftsättningen" pipeline"Storbritanniens nationella cybersäkerhetscenter, februari 2019.




