En kritisk sårbarhed bliver offentliggjort, advisoryen spreder sig, og inden for en time spørger nogen i virksomhedens chat: Er vi berørt? Log4Shell gjorde spørgsmålet berømt. CVE-2021-44228 ramte Log4j Core fra 2.0-beta9 op til 2.15.0, et bibliotek, der lå flere lag nede i afhængighedstræet i utallige Java-produkter, og de fleste teams måtte finde ud af, hvor det var, på den hårde måde.

Spørgsmålet lyder enkelt. Det er faktisk tre spørgsmål:

  1. Findes den sårbare komponent i noget, vi bygger eller leverer?
  2. Hvis ja, kan den så udnyttes i vores produkt?
  3. Siden hvornår, og i hvilke releases?

De fleste processer besvarer de to første. Det tredje er det, kunder, auditorer og myndigheder spørger om bagefter, og det er det sværeste at besvare i bakspejlet.

Trin 1: Find ud af, om komponenten er der

Virksomheder når som regel frem til et svar på en af fire måder, nogenlunde i rækkefølge efter modenhed.

Spørg rundt, og søg. Nogen skriver i Slack, udviklere søger efter pakkenavnet i deres repositories og lockfiles, og et regneark samler svarene. Det er stadig den mest almindelige metode. Den er langsom, den afhænger af, hvem der svarer, og den overser alt, der ikke er deklareret i en fil: afhængigheders afhængigheder, vendorede biblioteker, base-images og værktøjer installeret under buildet.

Tjek scannernes dashboards. Afhængighedsscannere markerer CVE'en pr. repository inden for få timer. Det er hurtigere, men en scanner rapporterer om den kode, den har foran sig i dag, som regel default-branchen. Den fortæller dig ikke, hvilke releases dine kunder kører, eller hvad et build for tre måneder siden faktisk trak ind.

Forespørg en SBOM-oversigt. Teams, der har en software bill of materials for hver release, kan stille ét spørgsmål på tværs af dem alle: Hvilke produkter og versioner indeholder de berørte versioner af denne pakke? Det er den første metode, der svarer for software, du har leveret, og ikke kun for software i repositoriet.

Match løbende. Når SBOM'er overvåges mod sårbarhedsdata, findes listen over berørte produkter, før nogen spørger. Chattråden starter med svaret i stedet for spørgsmålet.

Kvaliteten af hver metode afhænger af, hvad oversigten faktisk indeholder. De sædvanlige blinde vinkler er:

  • Transitive afhængigheder. Den sårbare pakke er sjældent en, du selv har tilføjet. Den kommer ind tre eller fire niveauer nede.
  • Alt, hvad manifestet ikke deklarerer. Pakker installeret af build-scripts, npx-værktøjer, Dockerfile-trin, gendannede caches og vendoreret C- og C++-kode.
  • Gamle releases. En branch, der ikke længere kan bygges, kan ikke scannes igen, men produktet bygget fra den kan stadig være i brug ude hos brugerne.

Trin 2: Afgør, om det betyder noget

En komponent kan være til stede uden at være en reel risiko, så næste trin er triage:

  • Version og konfiguration. Falder versionen præcis inden for det berørte interval? Er den sårbare funktion kompileret med og slået til?
  • Reachability. Kalder din kode overhovedet den sårbare funktion?
  • Eksponering. Kan komponenten nås fra netværket eller fra ikke-betroet input, eller bruges den kun på build-tidspunktet?
  • Afhjælpning. Er der sandboxing, en netværksbegrænsning eller en konfiguration, der blokerer udnyttelsen?
  • Tegn på udnyttelse. CVSS angiver alvorligheden, EPSS anslår sandsynligheden for, at en CVE bliver udnyttet inden for de næste 30 dage, og CISA's Known Exploited Vulnerabilities catalog viser dem, der allerede bliver udnyttet i praksis. Sammen afgør de, hvad der bliver set på først.

Trin 3: Registrér beslutningen

Resultatet registreres pr. produkt og version, i stigende grad som en VEX-erklæring (Vulnerability Exploitability eXchange). CISA's minimum requirements for VEX definerer fire statusser: not affected, affected, fixed og under investigation. En "not affected"-erklæring skal sige hvorfor, for eksempel fordi den sårbare kode ikke er til stede eller ikke kan nås af en angriber.

Den registrering er grundlaget for alt, hvad der følger: rettelsen og de releases, der indeholder den, sikkerhedsmeddelelsen til kunderne og enhver rapport, en myndighed forventer. Under EU's Cyber Resilience Act skal en producent for eksempel sende en tidlig advarsel om en aktivt udnyttet sårbarhed i sit produkt inden for 24 timer efter at være blevet opmærksom på den.

Trin 4: Beregn eksponeringsvinduet

"Er vi berørt?" har en anden halvdel, som ofte bliver sprunget over: Hvor længe var vi berørt?

Sårbarheden fandtes længe før, CVE'en blev offentliggjort. Log4Shell havde ligget i Log4j siden 2.0-beta9, der blev udgivet år før nogen afslørede den. Din eksponering begyndte den dag, et build første gang trak en sårbar version ind, og den sluttede den dag, det sidste build, der indeholdt den, blev erstattet. Du har brug for det vindue til at:

  • fortælle kunderne, hvilke af de releases, de kører, der er berørt, og ikke kun den seneste
  • afgrænse en hændelsesundersøgelse til den rigtige periode, hvis sårbarheden kan være blevet udnyttet
  • vise en auditor eller en myndighed, hvornår problemet kom ind i produktet, og hvornår rettelsen blev leveret

Det kan en scanning af dagens kode ikke give dig. Den aktuelle lockfile siger, hvad repositoriet vil have nu, ikke hvad hvert tidligere build installerede. Den eneste pålidelige kilde er en registrering af hvert build, foretaget mens det kørte og gemt bagefter.

Sådan besvarer CRACI det

CRACI kører dine GitHub Actions-jobs på sine egne runnere og registrerer hver pakke, hvert build faktisk trækker ind, direkte og transitivt, inklusive pakker installeret af scripts og gendannet fra caches. Hvert builds SBOM bliver gemt, så historikken allerede er der, når en CVE bliver offentliggjort.

Når en ny CVE dukker op, er svaret der allerede: hvert tidligere build og dets SBOM, hvilke af dem der indeholdt den sårbare afhængighed, direkte eller transitivt, og den periode, du var berørt. Intet regneark, ingen genscanning, ingen rekonstruktion ud fra lockfiles. Det første build, der indeholdt den, og det build, der fjernede den, giver dig eksponeringsvinduet, så langt tilbage som din opbevaring rækker (180 dage som standard, tilpasset opbevaring på Enterprise).

Når du ved det, kan en policy gate blokere builds, der indeholder denne CVE, så en senere afhængighedsopdatering eller en gendannet cache ikke i det stille kan bringe den sårbare version tilbage i en release.

Derfra har resten af processen noget at stå på:

  • CRACI overvåger SBOM'erne løbende, så nye CVE'er bliver matchet mod dine builds, uden at nogen spørger.
  • Sikkerhedsteams triagerer fund og sender dem til de teams, der ejer rettelsen, og CRACI understøtter VEX til at registrere resultatet.
  • CRACI's oversigt viser, hvilke softwareversioner der er deployet til hvilke produkter.
  • For CRA indsender CRACI den tidlige advarsel, underretningen og den endelige rapport på dine vegne.

Book en demo for at se build-historikken for et af dine egne repositories.