Direct naar inhoud

Verouderde en kwetsbare componenten

CWE-1104CWE-1035CWE-937OWASP A06:2021Bijgewerkt 3 september 20265 min leestijd

Frameworks, bibliotheken en servers waarvoor beveiligingsupdates bestaan die niet zijn doorgevoerd, dragen kwetsbaarheden die publiek gedocumenteerd zijn. Voor veel daarvan bestaat kant-en-klare aanvalscode. De aanvaller hoeft niets te ontdekken: hij leest de versie af en zoekt op wat er bekend is.

De meeste kwetsbaarheden in een applicatie moeten worden gevonden. Deze niet: ze staan in een openbare database, met een beschrijving, een ernstscore en vaak werkende aanvalscode erbij. Het enige dat een aanvaller hoeft te doen is vaststellen welke versie u draait. Hieronder leest u waarom dat zo eenvoudig is en hoe u het bijhouden beheersbaar maakt.

Wat zijn verouderde componenten?

Een moderne applicatie bestaat voor het overgrote deel uit code die u niet zelf hebt geschreven: het framework, de webserver, de database, de programmeertaal, tientallen tot honderden bibliotheken, en de containerlagen waarin dat alles draait. Verouderde en kwetsbare componenten zijn de onderdelen daarvan waarvoor beveiligingsupdates bestaan die u niet hebt doorgevoerd.

Deze categorie onderscheidt zich door de openbaarheid. Wanneer een kwetsbaarheid in een veelgebruikte component wordt gevonden, wordt die verantwoord gemeld, krijgt ze een CVE-nummer en wordt ze na het uitkomen van de update publiek beschreven. Die openbaarheid is nodig, beheerders moeten weten wat ze moeten patchen, maar hij werkt beide kanten op. Vanaf dat moment weet ook iedere aanvaller precies wat er mis is en hoe het te misbruiken valt.

Vergelijk het met een terugroepactie voor een slot waarvan bekend is geworden dat het met een specifieke handeling opengaat. De fabrikant levert een vervangend exemplaar. Wie dat niet monteert, heeft niet alleen een zwak slot, maar een slot waarvan de zwakte in een openbare handleiding staat beschreven.

Hoe misbruikt een aanvaller verouderde componenten?

De aanval begint met verkennen, en uw applicatie werkt daar vaak zelf aan mee.

Kwetsbaar:

HTTP/1.1 200 OK
Server: Apache/2.4.29 (Ubuntu)
X-Powered-By: PHP/7.2.24
X-Generator: Drupal 7.58
<script src="/js/jquery-1.8.3.min.js"></script>

In vier regels staat een complete inventarisatie. Een aanvaller zoekt deze versies op in een publieke kwetsbaarhedendatabase, vindt welke problemen bekend zijn en of daar aanvalscode voor beschikbaar is. Het onderzoek dat hij daarvoor moet doen bestaat uit het lezen van een pagina.

Dit gaat niet alleen om servers. Ook uw afhankelijkheden dragen risico’s, vaak zonder dat u ze bewust hebt gekozen:

$ npm audit
found 34 vulnerabilities (12 moderate, 18 high, 4 critical)
  critical  Prototype Pollution in lodash <4.17.21
  high      Regular Expression Denial of Service in semver <7.5.2

Van die vierendertig meldingen zijn er in de praktijk enkele werkelijk relevant, omdat de rest zit in code die uw applicatie nooit aanroept. Juist die nuance is nodig om te voorkomen dat het overzicht wordt genegeerd.

Veilig:

De oplossing is geen eenmalige opschoning maar een proces dat blijft draaien:

# In de ontwikkelstraat: bouw faalt bij een ernstig, bereikbaar probleem
- name: Controle op kwetsbare afhankelijkheden
  run: npm audit --audit-level=high

- name: Inventarisatie vastleggen
  run: npm sbom --sbom-format cyclonedx > sbom.json
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8

De headers geven nu geen versie-informatie meer prijs. Dat verhelpt de kwetsbaarheid niet, de verouderde component blijft verouderd, maar het dwingt een aanvaller wel om te zoeken in plaats van te lezen, en het maakt geautomatiseerd scannen op kwetsbare versies aanzienlijk minder effectief.

Het verbergen van versienummers is een aanvulling, geen maatregel. Een aanvaller kan de versie vaak alsnog afleiden uit gedrag, uit de aanwezigheid van specifieke bestanden of uit de exacte formulering van foutmeldingen. Beschouw het verbergen nooit als alternatief voor het bijwerken zelf.

Wat is de impact van verouderde componenten?

De ernst loopt van middelzwaar tot kritiek, en wordt volledig bepaald door de betreffende kwetsbaarheid. Dat is meteen wat deze categorie lastig maakt: het is geen fout met een vaste zwaarte, maar een categorie waarin alles kan zitten, van een klein informatielek tot code-uitvoering op afstand zonder authenticatie.

De kritieke gevallen zijn bekend geworden onder eigen namen. Log4Shell in een logbibliotheek en de kwetsbaarheid in een populair contentmanagementsysteem leidden binnen dagen tot massale, geautomatiseerde uitbuiting. Wie op dat moment een kwetsbare versie draaide, werd niet gericht uitgekozen maar simpelweg gevonden door een scanner die het hele internet afliep.

Die geautomatiseerde aard is het kenmerkende. Bij de meeste kwetsbaarheden moet een aanvaller belangstelling hebben voor juist uw organisatie. Hier niet: er wordt op grote schaal gescand op kwetsbare versies, en alles wat reageert wordt aangevallen. Uw omvang of zichtbaarheid doet er niet toe. Wat telt is hoeveel tijd er zit tussen het uitkomen van de update en het moment waarop u hem doorvoert.

Hoe spoor je verouderde componenten op?

Van buitenaf begint het bij het aflezen van wat de applicatie zelf prijsgeeft: versie-informatie in HTTP-headers, in HTML-commentaar, in de bestandsnamen van JavaScript-bibliotheken, in de standaardbestanden van het gebruikte platform en in foutmeldingen. Een tester vergelijkt de gevonden versies met publieke databases en beoordeelt of de bekende kwetsbaarheden in deze opstelling werkelijk bereikbaar zijn.

Aan de binnenkant gaat het om de inventarisatie van afhankelijkheden. Daarbij hoort nadrukkelijk ook wat u indirect binnenhaalt: een bibliotheek die u bewust hebt gekozen, brengt er vaak tientallen mee die niemand heeft beoordeeld. Er wordt gekeken of er een actueel overzicht bestaat, of er een proces is dat op nieuwe meldingen reageert, en hoe lang het in de praktijk duurt voordat een update wordt doorgevoerd. AssistSec beoordeelt daarbij niet alleen welke meldingen er openstaan, maar of het kwetsbare pad in uw applicatie daadwerkelijk kan worden bereikt, dat onderscheid bepaalt of iets met spoed moet of gepland kan worden.

Hoe voorkom je verouderde componenten?

  • Houd een actueel overzicht bij van alle componenten en versies, inclusief indirecte afhankelijkheden.
  • Controleer automatisch op bekende kwetsbaarheden in uw ontwikkelstraat en laat de bouw falen bij ernstige gevallen.
  • Beoordeel per melding of het kwetsbare pad in uw applicatie bereikbaar is, en stel op basis daarvan prioriteiten.
  • Draai uitsluitend versies die nog beveiligingsupdates ontvangen; plan vervanging vóór het einde van de ondersteuning.
  • Werk ook frontend-bibliotheken bij; die draaien op uw domein en met uw sessie.
  • Verwijder componenten en functionaliteit die u niet gebruikt, want ongebruikte code moet wel worden onderhouden.
  • Verberg versie-informatie in headers en foutmeldingen als aanvullende laag.
  • Leg vast hoe snel u na het uitkomen van een update handelt, en meet of u die norm haalt.
  • Volg meldingen over de componenten die u gebruikt actief, in plaats van af te wachten.

Bronnen

Veelgestelde vragen

Moet ik alles altijd op de nieuwste versie draaien?

Niet per se de nieuwste, wel een versie die nog beveiligingsupdates ontvangt. Een langdurig ondersteunde uitgave die actief wordt onderhouden is prima. Wat u moet vermijden is een versie waarvoor geen updates meer verschijnen, want dan blijft elke nieuwe kwetsbaarheid open staan.

Is een kwetsbaarheid in een bibliotheek altijd uitbuitbaar?

Nee, en dat is belangrijk bij het stellen van prioriteiten. Een kwetsbaarheid in een functie die uw applicatie nooit aanroept, is theoretisch. Analyseer daarom niet alleen welke versies u draait, maar ook of het kwetsbare pad werkelijk bereikbaar is. Dat voorkomt dat u verdrinkt in meldingen.

Waarom worden frontend-bibliotheken vaak vergeten?

Omdat ze bij de gebruiker draaien en niet op uw server, waardoor ze buiten het gebruikelijke serverbeheer vallen. Toch draaien ze op uw domein en met uw sessie. Een verouderde jQuery met een bekend probleem is een reëel risico voor uw bezoekers.

Hoe ga ik om met een kwetsbaarheid zonder update?

Beoordeel eerst of het kwetsbare pad in uw situatie bereikbaar is. Zo ja, beperk de toegang tot de betreffende functionaliteit, plaats er een filter voor of schakel de component tijdelijk uit. Documenteer die keuze en plan de vervanging; een tijdelijke maatregel die blijft staan wordt een structureel risico.

Verwante artikelen

Druk op / om te zoeken · Esc