Waarom geheimen in JavaScript-bundels nog steeds worden gemist

Gelekte API-sleutels zijn niet langer ongebruikelijk, net als de inbreuken die daarop volgen. Dus waarom worden gevoelige tokens nog steeds zo gemakkelijk blootgesteld?

Om hier achter te komen heeft het onderzoeksteam van Intruder gekeken naar wat traditionele kwetsbaarheidsscanners feitelijk bestrijken en een nieuwe methode voor het detecteren van geheimen ontwikkeld om de hiaten in de bestaande benaderingen aan te pakken.

Door dit op grote schaal toe te passen door 5 miljoen applicaties te scannen, werden ruim 42.000 blootgestelde tokens in 334 soorten geheimen onthuld, waardoor een grote klasse van gelekte geheimen werd blootgelegd die niet goed wordt afgehandeld door bestaande tools, vooral in applicaties met één pagina (SPA’s).

In dit artikel ontleden we bestaande methoden voor het detecteren van geheimen en onthullen we wat we ontdekten toen we miljoenen applicaties scanden op geheimen die verborgen waren in JavaScript-bundels.

Gevestigde methoden voor het detecteren van geheimen (en hun beperkingen)

Traditionele geheimendetectie

De traditionele, volledig geautomatiseerde aanpak voor het detecteren van applicatiegeheimen is het doorzoeken van een reeks bekende paden en het toepassen van reguliere expressies die overeenkomen met bekende geheime formaten.

Hoewel deze methode nuttig is en bepaalde risico’s kan opvangen, heeft deze duidelijke beperkingen en worden niet alle soorten lekken gedetecteerd, vooral niet de lekken waarbij de scanner de applicatie moet spideren of authenticeren.

Een goed voorbeeld hiervan is de GitLab-sjabloon voor persoonlijke toegangstokens van Nuclei. De scanner krijgt een basis-URL, bijvoorbeeld https://portal.intruder.io/, waardoor de sjabloon:

  1. Doe een HTTP GET-verzoek naar https://portal.intruder.io/
  2. Inspecteer de directe reactie op dat ene verzoek, het negeren van andere pagina’s en bronnen zoals JavaScript-bestanden
  3. Probeer het patroon van een persoonlijk toegangstoken van GitLab te identificeren
  4. Indien gevonden, dien dan een vervolgverzoek in bij de openbare API van GitLab om te controleren of het token actief is
  5. Indien actief, meld dan een probleem

Dit is duidelijk een eenvoudig voorbeeld, maar deze aanpak is effectief. Vooral als sjablonen veel paden definiëren waar geheimen vaak worden onthuld.

Dit formaat is typerend voor infrastructuurscanners, die doorgaans geen headless browser gebruiken. Wanneer de scanner de basis-URL krijgt om te scannen (bijvoorbeeld https://portal.intruder.io), zullen daaropvolgende verzoeken die door een browser zouden worden gedaan (zoals de JavaScript-bestanden die nodig zijn om de pagina weer te geven, bijvoorbeeld https://portal.intruder.io/assets/index-DzChsIZu.js) niet worden gedaan met behulp van deze ouderwetse aanpak.

Dynamische applicatiebeveiligingstests (DAST)

Dynamic Application Security Testing (DAST)-tools zijn over het algemeen een robuustere manier om applicaties te scannen, en hebben doorgaans een complexere functionaliteit, waardoor volledige spidering van applicaties, ondersteuning voor authenticatie en een breder vermogen bij het detecteren van zwakke punten in applicatielagen mogelijk zijn. DAST-scanners lijken misschien de natuurlijke optie voor geheimendetectie in front-ends van applicaties. Er mag niets zijn dat een DAST-scanner ervan weerhoudt beschikbare JavaScript-bestanden te ontdekken of naar geheimen daarin te scannen.

Dit type scannen is echter duurder, vereist een diepgaande configuratie en is in werkelijkheid meestal gereserveerd voor een klein aantal hoogwaardige toepassingen. Het is bijvoorbeeld onwaarschijnlijk dat u een DAST-scanner configureert voor elke toepassing die u op een breed digitaal landgoed heeft. Bovendien implementeren veel DAST-tools niet een voldoende breed scala aan reguliere expressies in vergelijking met bekende opdrachtregelprogramma’s.

Dit laat een duidelijke leemte achter zou moeten wordt gedekt door de traditionele infrastructuurscanner, maar wordt niet gedekt door DAST-scanners, en wordt naar alle waarschijnlijkheid ook niet gedekt vanwege implementatie-, budget- en onderhoudsbeperkingen.

Statische applicatiebeveiligingstests (SAST)

Static Application Security Testing (SAST)-tools analyseren de broncode om kwetsbaarheden te identificeren en zijn een primaire manier om geheimen te detecteren voordat code de productie bereikt. Ze zijn effectief in het onderscheppen van hardgecodeerde inloggegevens en het voorkomen van bepaalde vormen van blootstelling.

We ontdekten echter dat SAST-methoden ook niet het volledige plaatje dekken – en opnieuw glipten sommige geheimen in JavaScript-bundels door de gaten op een manier die statische analyse zou missen.

Een controle op geheimendetectie bouwen voor JavaScript-bundels

Toen we met dit onderzoek begonnen, was het niet duidelijk hoe vaak dit probleem zou voorkomen. Worden geheimen daadwerkelijk gebundeld in JavaScript-front-ends, en zijn deze wijdverspreid genoeg om een ​​geautomatiseerde aanpak te rechtvaardigen?

Om daar achter te komen, hebben we een geautomatiseerde controle gebouwd en ongeveer 5 miljoen sollicitaties gescand. Het resultaat was een groot aantal opnames, aanzienlijk meer dan we hadden verwacht. Het uitvoerbestand alleen al was meer dan 100 MB platte tekst en bevatte meer dan 42.000 tokens in 334 verschillende soorten geheimen.

We hebben niet elk resultaat volledig beoordeeld, maar onder de monsters die we hebben beoordeeld, hebben we een aantal blootstellingen met een grote impact geïdentificeerd.

Wat we hebben gevonden

Tokens voor codeopslagplaatsen

De meest impactvolle blootstellingen die we identificeerden waren tokens voor coderepositoryplatforms zoals GitHub en GitLab. In totaal hebben we 688 tokens gevonden, waarvan er vele nog steeds actief waren en volledige toegang gaven tot repositories.

In één geval, hieronder weergegeven, werd een persoonlijk toegangstoken van GitLab rechtstreeks in een JavaScript-bestand ingebed. Het token was bedoeld om toegang te bieden tot alle privérepository’s binnen de organisatie, inclusief CI/CD-pijplijngeheimen voor verdere services zoals AWS en SSH.

API-sleutels voor projectbeheer

Een andere belangrijke blootstelling betrof een API-sleutel voor Linear, een projectmanagementapplicatie, rechtstreeks ingebed in front-endcode:

Het token maakte de volledige Linear-instantie van de organisatie openbaar, inclusief interne tickets, projecten en links naar downstream-services en SaaS-projecten.

En meer

We hebben onthulde geheimen geïdentificeerd via een breed scala aan andere services, waaronder:

CAD-software-API’s – toegang tot gebruikersgegevens, metadata van projecten en gebouwontwerpen, waaronder een ziekenhuis

Linkverkorters – mogelijkheid om links te creëren en op te sommen

E-mailplatforms – toegang tot mailinglijsten, campagnes en abonneegegevens

Webhooks voor chat- en automatiseringsplatforms – 213 Slack, 2 Microsoft Teams, 1 Discord en 98 Zapier, allemaal actief

PDF-converters – toegang tot tools voor het genereren van documenten van derden

Verkoopintelligentie- en analyseplatforms – toegang tot geschrapte bedrijfs- en contactgegevens

Verzend uw geheimen niet

Shift-links-besturingselementen zijn belangrijk. SAST, repositoryscanning en IDE-vangrails vangen echte problemen op en voorkomen blootstelling aan hele klassen. Maar zoals uit dit onderzoek blijkt, dekken ze niet elk pad dat een geheim kan bewandelen om tot productie te komen.

Geheimen die tijdens de bouw en implementatie worden geïntroduceerd, kunnen deze beveiligingen omzeilen en in de front-endcode terechtkomen, lang na het punt waarop de shift-left-controles al zijn uitgevoerd. En dit probleem zal alleen maar groter worden naarmate automatisering en door AI gegenereerde code steeds gebruikelijker worden.

Daarom is ‘spiping’ van applicaties op één pagina nodig om geheimen te achterhalen voordat ze in productie gaan. We hebben geautomatiseerde detectie van SPA-geheimen in Intruder ingebouwd, zodat teams dit daadwerkelijk kunnen onderscheppen. Meer informatie.

Thijs Van der Does